다음과 같은 몇 가지 코드 예제를 보았습니다.
if not someobj:
#do something
그러나 왜 안하고 있는지 궁금합니다.
if someobj == None:
#do something
차이점이 있습니까? 하나는 다른 것보다 장점이 있습니까?
X != None
?
다음과 같은 몇 가지 코드 예제를 보았습니다.
if not someobj:
#do something
그러나 왜 안하고 있는지 궁금합니다.
if someobj == None:
#do something
차이점이 있습니까? 하나는 다른 것보다 장점이 있습니까?
X != None
?
답변:
첫 번째 테스트에서 Python은 객체가 bool
아직 값이 아닌 경우 값 으로 변환하려고 시도합니다 . 대략, 우리는 목표를 묻습니다 : 당신은 의미가 있습니까? 이것은 다음 알고리즘을 사용하여 수행됩니다.
객체에 __nonzero__
특수한 메소드 가있는 경우 (숫자 내장 int
및 및 float
)이 메소드를 호출합니다. bool
직접 사용되는 int
값 또는 False
0과 같은 경우 고려 되는 값을 리턴해야합니다 .
객체가있는 경우 그렇지 않은 경우, __len__
특별한 방법을 (같은 컨테이너에 내장 된 기능을 수행 list
, dict
, set
, tuple
, 그것은 용기를 고려,이 메소드를 호출, ...) False
가 (길이가 제로) 비어있는 경우.
그렇지 않은 경우, 객체는 어떤 경우에도 고려 True
되지 않는 한 None
고려됩니다 False
.
두 번째 테스트에서는 객체와의 동등성이 비교됩니다 None
. 여기서 우리는 "당신은이 다른 가치와 같은가?" 이것은 다음 알고리즘을 사용하여 수행됩니다.
객체에 __eq__
메소드 가있는 경우이 메소드가 호출되고 리턴 값이 값으로 변환되어 bool
의 결과를 판별하는 데 사용됩니다 if
.
그렇지 않으면 객체에 __cmp__
메소드가 있으면 호출됩니다. 이 함수는 int
두 객체의 순서를 나타내는 ( -1
if self < other
, 0
if self == other
, +1
if self > other
)를 반환해야합니다 .
그렇지 않으면, 객체는 동일성에 대해 비교된다 (즉, is
운영자에 의해 테스트 될 수있는 동일한 객체를 참조한다 ).
is
연산자를 사용하여 가능한 또 다른 테스트가 있습니다 . 우리는 그 대상에게 "이 특별한 대상입니까?"라고 물을 것입니다.
일반적으로 숫자가 아닌 값으로 첫 번째 테스트를 사용하고 동일한 특성 (두 문자열, 두 숫자 등)의 객체를 비교할 때 동등성 테스트를 사용하고 다음과 같은 경우에만 ID를 확인하는 것이 좋습니다. 센티넬 값을 사용하여 ( None
exemple하는 부재 필드에 대한 초기화, 또는 사용하지 않을 때하는 의미 getattr
또는 __getitem__
메소드).
요약하면 다음과 같습니다.
>>> class A(object):
... def __repr__(self):
... return 'A()'
... def __nonzero__(self):
... return False
>>> class B(object):
... def __repr__(self):
... return 'B()'
... def __len__(self):
... return 0
>>> class C(object):
... def __repr__(self):
... return 'C()'
... def __cmp__(self, other):
... return 0
>>> class D(object):
... def __repr__(self):
... return 'D()'
... def __eq__(self, other):
... return True
>>> for obj in ['', (), [], {}, 0, 0., A(), B(), C(), D(), None]:
... print '%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s' % \
... (repr(obj), bool(obj), obj == None, obj is None)
'': bool(obj) -> False, obj == None -> False, obj is None -> False
(): bool(obj) -> False, obj == None -> False, obj is None -> False
[]: bool(obj) -> False, obj == None -> False, obj is None -> False
{}: bool(obj) -> False, obj == None -> False, obj is None -> False
0: bool(obj) -> False, obj == None -> False, obj is None -> False
0.0: bool(obj) -> False, obj == None -> False, obj is None -> False
A(): bool(obj) -> False, obj == None -> False, obj is None -> False
B(): bool(obj) -> False, obj == None -> False, obj is None -> False
C(): bool(obj) -> True, obj == None -> True, obj is None -> False
D(): bool(obj) -> True, obj == None -> True, obj is None -> False
None: bool(obj) -> False, obj == None -> True, obj is None -> True
이것들은 실제로 모두 나쁜 습관입니다. 옛날 옛적에, None과 False를 자연스럽게 비슷한 것으로 취급하는 것은 괜찮은 것으로 간주되었습니다. 그러나 Python 2.2 이후로는 이것이 최선의 정책이 아닙니다.
첫째, if x
또는 if not x
일종의 테스트 를 수행 할 때 Python은 암시 적 x
으로 부울 로 변환 해야합니다. bool
기능에 대한 규칙 은 거짓 인 뗏목을 설명합니다. 그 밖의 모든 것은 사실입니다. x의 값이 처음부터 부울이 아니었다면,이 암묵적인 변환은 실제로 가장 명확한 방법이 아닙니다.
Python 2.2 이전에는 bool 함수가 없었으므로 덜 명확했습니다.
둘째, 실제로 테스트해서는 안됩니다 == None
. is None
및을 사용해야합니다 is not None
.
PEP 8, Python 코드 용 스타일 안내서를 참조하십시오 .
- Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators. Also, beware of writing "if x" when you really mean "if x is not None" -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!
싱글 톤은 몇 개입니까? 다섯 : None
, True
, False
, NotImplemented
와 Ellipsis
. 당신이 정말로 가능성은 희박하기 때문에 사용 NotImplemented
하거나 Ellipsis
, 당신은 말을하지 않을 것 if x is True
(단순히이 때문에 if x
많은 명확), 당신은거야 오직 테스트 None
.
때문에이 None
거짓으로 간주되는 유일한 것이 아니다.
if not False:
print "False is false."
if not 0:
print "0 is false."
if not []:
print "An empty list is false."
if not ():
print "An empty tuple is false."
if not {}:
print "An empty dict is false."
if not "":
print "An empty string is false."
False
, 0
, ()
, []
, {}
그리고 ""
모든 다른 None
당신이 개 코드 조각은 그래서, 하지 와 같습니다.
또한 다음을 고려하십시오.
>>> False == 0
True
>>> False == ()
False
if object:
평등 검사 가 아닙니다 . 0
, ()
, []
, None
, {}
, 등이 있습니다 서로 모두 다른,하지만 그들은 모두 평가 False로.
이것은 다음과 같은 단락 표현의 "마법"입니다.
foo = bar and spam or eggs
이것은 속기입니다 :
if bar:
foo = spam
else:
foo = eggs
당신이 정말로 작성해야하지만 :
foo = spam if bar else egg
PEP 8 - 파이썬 코드에 대한 스타일 가이드는 사용에 권장 입니다 또는 아닙니다 당신이 없음 다움을 테스트하는 경우
- Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators.
반면 None-ness 이상을 테스트하는 경우 부울 연산자를 사용해야합니다.
당신이 묻는다면
if not spam:
print "Sorry. No SPAM."
스팸 의 __nonzero__ 메소드 가 호출됩니다. 파이썬 매뉴얼에서 :
__nonzero__ ( self ) 실제 값 테스트 및 내장 연산 bool ()을 구현하기 위해 호출됩니다. False 또는 True 또는 해당 정수 0 또는 1을 리턴해야합니다.이 메소드가 정의되지 않은 경우 __len __ ()이 정의 된 경우 호출됩니다 (아래 참조). 클래스가 __len __ () 또는 __nonzero __ ()을 정의하지 않으면 모든 인스턴스가 true로 간주됩니다.
당신이 묻는다면
if spam == None:
print "Sorry. No SPAM here either."
스팸 의 __eq__ 메소드는 None 인수와 함께 호출됩니다 .
사용자 정의 가능성에 대한 자세한 내용은 https://docs.python.org/reference/datamodel.html#basic-customization 에서 Python 문서를 참조하십시오.
이 두 비교는 다른 목적으로 사용됩니다. 전자는 무언가의 부울 값을 확인하고 두 번째는 None 값을 가진 동일성을 확인합니다.
대답은 "그것은 달려있다"입니다.
이 컨텍스트에서 0, "", [] 및 False (전체가 아님)를 None과 동일하다고 생각하면 첫 번째 예제를 사용합니다.
개인적으로 나는 여러 언어에 걸쳐 일관된 접근 방식을 선택했습니다. if (var)
var가 부울로 선언 된 경우에만 (또는 C에서 특정 유형이없는 경우에만) 동등한 작업을 수행합니다. 나는 실수로 다른 유형을 여기에서 사용하지 않도록하기 위해 이러한 변수 앞에 접두사를 붙입니다 b
( bVar
실제로 그렇습니다 ).
수많은 복잡한 규칙이있을 때 부울에 대한 암시 적 캐스팅을 좋아하지 않습니다.
물론 사람들은 동의하지 않을 것입니다. 일부는 더 멀리 가고, 나는 if (bVar == true)
내 작업에서 Java 코드에서 볼 수 있습니다 (내 취향에 너무 중복되어 있습니다!), 다른 일부는 너무 간결한 구문을 좋아합니다 while (line = getNextLine())
.