if 문에서 조건 평가 순서에 의존하는 것이 안전합니까?
my_var
None이 될 수있을 때 다음 형식을 사용하는 것이 나쁜 습관 입니까?
if my_var and 'something' in my_var:
#do something
문제는 'something' in my_var
my_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_var
에 True
나 False
.
귀하의 경우에는 구별이 중요하지 않다고 확신하지만,보다 일반적인 경우에는 변수가 아닌 것으로 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.
'Development Tip' 카테고리의 다른 글
특정 연령보다 오래된 모든 Linux 프로세스를 어떻게 종료합니까? (0) | 2020.11.14 |
---|---|
Java Swing GUI에 대한 자동화 된 테스트 (0) | 2020.11.14 |
C에서 순환 버퍼를 어떻게 구현합니까? (0) | 2020.11.14 |
여러 스레드가 사용 가능할 때 여러 CPU를 사용하도록 강제 (0) | 2020.11.14 |
캐럿 / 커서 위치를 문자열 값 WPF 텍스트 상자의 끝으로 설정 (0) | 2020.11.14 |