Development Tip

if 문에서 조건 평가 순서에 의존하는 것이 안전합니까?

yourdevel 2020. 11. 14. 11:12
반응형

if 문에서 조건 평가 순서에 의존하는 것이 안전합니까?


my_varNone이 수있을 때 다음 형식을 사용하는 것이 나쁜 습관 입니까?

if my_var and 'something' in my_var:
    #do something

문제는 'something' in my_varmy_var가 None이면 TypeError 가 발생한다는 것입니다.

또는 다음을 사용해야합니다.

if my_var:
    if 'something' in my_var:
        #do something

또는

try:
    if 'something' in my_var:
        #do something
except TypeError:
    pass

질문을 다시 말하면, 위 중 어느 것이 Python에서 가장 좋은 방법입니까 (있는 경우)?

대안을 환영합니다!


특히 지적한 문제로 인해 조건부 순서에 의존하는 것이 안전합니다 ( 여기서 Python 참조 ). 일련의 조건부에서 문제를 일으킬 수있는 평가를 단락시킬 수있는 것은 매우 유용합니다.

이러한 종류의 코드는 대부분의 언어에서 나타납니다.

IF exists(variable) AND variable.doSomething()
    THEN ...

예, 안전합니다. 언어 참조에 명시적이고 명확하게 정의되어 있습니다.

식은 x and y먼저 다음을 평가합니다 x. 경우 x이며 false, 그 값이 리턴되고; 그렇지 않으면 y평가되고 결과 값이 반환됩니다.

식은 x or y먼저 다음을 평가합니다 x. 경우 x사실, 그 값이 반환됩니다; 그렇지 않으면 y평가되고 결과 값이 반환됩니다.


나는 여기서 약간 현학적 인 것 같지만 가장 좋은 대답은

if my_var is not None and 'something' in my_var:
    #do something

차이점은 대한 명시 적으로 확인되는 None것이 아니라의 암시 적 변환 my_varTrueFalse.

귀하의 경우에는 구별이 중요하지 않다고 확신하지만,보다 일반적인 경우에는 변수가 아닌 것으로 None평가 될 수 있습니다 ( False예 : 정수 값 0또는 빈 목록).

그래서 안전하다는 다른 포스터의 주장과는 반대로, 당신이 노골적인 한 안전하다고 말하고 싶습니다. 확신이 없다면 다음과 같은 매우 인위적인 클래스를 고려하십시오.

class Contrived(object):
    def __contains__(self, s):
        return True
    def __nonzero__(self):
        return False

my_var = Contrived()
if 'something' in my_var:
    print "Yes the condition is true"
if my_var and 'something' in my_var:
    print "But this statement won't get reached."
if my_var is not None and 'something' in my_var:
    print "Whereas this one will."

예, 이것이 현실적인 예가 아니라는 것을 알고 있지만, 특히 None기본 함수 인수를 나타내는 데 사용되는 경우 실제 코드에서 변형이 발생 합니다.


완벽하게 안전하며 항상 그렇게합니다.


나는 try / except와 함께 갈 것이지만 변수에 대해 아는 것에 달려 있습니다.

If you are expecting that the variable will exist most of the time, then a try/except is less operations. If you are expecting the variable to be None most of the time, then an IF statement will be less operations.


It's not that simple. As a C# dude I am very used to doing something like:

if(x != null && ! string.isnullorempty(x.Name))
{
   //do something
}

The above works great and is evaluated as expected. However in VB.Net the following would produce a result you were NOT expecting:

If Not x Is Nothing **And** Not String.IsNullOrEmpty(x.Name) Then

   'do something

End If

The above will generate an exception. The correct syntax should be

If Not x Is Nothing **AndAlso** Not String.IsNullOrEmpty(x.Name) Then

   'do something

End If

Note the very subtle difference. This had me confused for about 10 minutes (way too long) and is why C# (and other) dudes needs to be very careful when coding in other languages.

참고URL : https://stackoverflow.com/questions/752373/is-it-safe-to-rely-on-condition-evaluation-order-in-if-statements

반응형