답변:
진술
if A:
호출하고 A.__nonzero__()
( 특수 메서드 이름 설명서 참조 ) 해당 함수의 반환 값을 사용합니다. 요약은 다음과 같습니다.
object.__nonzero__(self)
진실 가치 테스트 및 기본 제공 작업을 구현하기 위해 호출됩니다
bool()
. 반환해야False
하거나True
, 또는 정수 동등0
또는1
. 이 메소드가 정의되지 않은 경우이 메소드가 정의 된__len__()
경우 호출되며 결과가 0이 아닌 경우 오브젝트는 참으로 간주됩니다. 클래스가__len__()
nor를 정의하지 않으면__nonzero__()
모든 인스턴스가 true로 간주됩니다.
반면에
if A is not None:
비교 만을 기준 A
으로 None
그 동일한인지 여부를 확인한다.
if object(): pass
루프 당 ~ 0.130 usec if object() is not None: pass
이고 ~ 0.135 usec입니다. 어쨌든 성능을 사용하여이 두 가지 중 하나를 선택 하지 말고 동등하지 않기 때문에 작동 방식의 차이점을 살펴보십시오 .
if A is not None
는 비교하기 때문에 느리게 보이며 내장 싱글 톤 None
을 중개 단계로 로드하여 비교해야합니다 A
(을보십시오 dis.dis()
). 내가 틀렸지 만 if A:
진실이 아닌 진실의 가치를 시험하고 싶어하는 즉시 더 효율적인 것처럼 나를 교정하십시오 None
.
python -m timeit -s"a=0" "if a: pass" "else: pass"
것보다 빠르지 python -m timeit -s"a=0" "if a is None: pass" "else: pass"
만 python -m timeit -s"a=1" "if a: pass" "else: pass"
느립니다. 플랫폼에 따라 다를 수 있습니다. 같은 결과를 얻으십시오
is None
테스트는 실제로 가장 느 렸습니다 . pypy에서 그들은 모두 똑같이 측정했습니다 :)
PEP8 로 작성된 :
없음 과 같은 싱글 톤과의 비교 는 항상 등호 연산자가 아닌 'is'또는 'is not'으로 수행해야합니다 .
또한 "x가 None이 아닌 경우"를 의미 할 때 "if x"를 쓰지 않도록주의하십시오. 예를 들어 기본값이 None 인 변수 또는 인수가 다른 값으로 설정되어 있는지 테스트 할 때. 다른 값에는 부울 컨텍스트에서 false 일 수있는 유형 (예 : 컨테이너)이있을 수 있습니다!
None
진실 값 확인에만 관심이 있습니다. 이 경우, if A:
(A을보다 효율적으로 보인다 dis.dis()
내장을로드하는 추가 단계가, None
와,와 비교 if A is not None:
만이 있지만, jump_if
다른 경우).
적절한 결과가 없으면 많은 함수가 None을 반환합니다. 예를 들어, .first()
결과에 행이 없으면 SQLAlchemy 쿼리의 메서드는 None을 반환합니다. 0을 리턴 할 수있는 값을 선택하고 실제로 0인지 또는 쿼리에 결과가 전혀 없는지 알아야한다고 가정하십시오.
일반적인 관용구는 함수 또는 메서드의 선택적 인수에 기본값 None을 부여한 다음 해당 값이 None인지 테스트하여 값이 지정되었는지 확인하는 것입니다. 예를 들면 다음과 같습니다.
def spam(eggs=None):
if eggs is None:
eggs = retrievefromconfigfile()
그것을 다음과 비교하십시오 :
def spam(eggs=None):
if not eggs:
eggs = retrievefromconfigfile()
전화 할 경우 후자에 무슨 일이 spam(0)
나 spam([])
? 함수는 (잘못된) 값을 전달하지 않았 음을 감지 eggs
하고 기본값을 계산합니다. 아마 당신이 원하는 것이 아닐 것입니다.
또는 "주어진 계정에 대한 거래 목록을 반환"과 같은 방법을 상상해보십시오. 계정이 없으면 None을 반환 할 수 있습니다. 이것은 비어있는 목록을 반환하는 것과 다릅니다 ( "이 계정은 존재하지만 기록 된 트랜잭션이 없음"을 의미 함).
마지막으로 데이터베이스로 돌아갑니다. NULL과 빈 문자열 사이에는 큰 차이가 있습니다. 빈 문자열은 일반적으로 "여기에 값이 있으며 그 값은 전혀 없습니다"라고 말합니다. NULL은 "이 값을 입력하지 않았습니다"라고 말합니다.
각각의 경우에을 사용하려고합니다 if A is None
. "False로 캐스트되는 모든 값"뿐만 아니라 특정 값 (없음)을 확인하고 있습니다.
그들은 매우 다른 일을 합니다.
아래의 검사 A는 값을 제외하고 무엇이든이있는 경우 False
, []
, None
, ''
와 0
. A 의 값 을 확인합니다 .
if A:
아래는 A가 없음과 다른 객체인지 확인합니다. A와 None 의 참조 (메모리 주소)를 확인하고 비교합니다 .
if A is not None:
업데이트 : 추가 설명
많은 경우 두 사람이 같은 일을하는 것처럼 보이므로 많은 사람들이 서로 바꿔서 사용합니다. 정말 나쁜 생각입니다. 두 사람이 동일한 결과를 얻는 이유는 인턴 또는 다른 것과 같은 인터프리터 / 컴파일러의 최적화로 인해 순수한 우연의 일치 로 여러 번 발생합니다 .
이러한 최적화를 염두에두고 동일한 값의 정수와 문자열은 동일한 메모리 공간을 사용합니다. 아마도 두 개의 개별 문자열이 동일한 것처럼 작동하는 이유를 설명합니다.
> a = 'test'
> b = 'test'
> a is b
True
> a == b
True
다른 것들도 똑같이 동작하지 않습니다 ..
> a = []
> b = []
> a is b
False
> a == b
True
두 목록에는 분명히 자신의 기억이 있습니다. 놀랍게도 튜플은 문자열처럼 행동합니다.
> a = ()
> b = ()
> a is b
True
> a == b
True
아마도 이것은 튜플이 변경되지 않도록 보장되기 때문에 동일한 메모리를 재사용하는 것이 좋습니다.
결론은 우연의 일치에 의존 할 수 없다는 것 입니다. 오리처럼 because다고해서 오리라는 의미는 아닙니다. 사용 is
하고 ==
당신이 정말로 확인하려는 작업에 따라 달라집니다. is
우리가 종종 넘어가는 산문과 같은 읽기 때문에 이러한 것들을 디버깅하기 가 어려울 수 있습니다 .
None
단일 톤이며 구현 세부 정보가 아닙니다 (int 또는 string interning과 달리). 나는 당신이 무엇을 의미하는지 잘 모르겠습니다.
None
과 다르게 int
또는 인트로 str
인해 작동 하지 않습니다 . 내 요점은이다 is
와 ==
다른 것을 확인하고 있습니다; 첫 번째는 메모리 주소를 확인하고 두 번째는 메모리 주소의 내용을 확인합니다.
None은 일반적으로 초기화되지 않은 변수를 지정하는 Python의 특별한 값입니다 . A에이 특정 값이 없는지 테스트하려면 다음을 사용하십시오.
if A is not None
Falsey 값은 Python의 특수 객체 클래스입니다 (예 : false, []). A가 거짓인지 테스트하려면 다음을 사용하십시오.
if not A
따라서 두 표현은 같지 않으며 동의어로 취급하지 않는 것이 좋습니다.
PS None도 거짓이므로 첫 번째 표현은 두 번째 표현을 의미합니다. 그러나 두 번째는 None 이외의 다른 잘못된 값을 다룹니다. 자 ... A에서 없음 이외의 다른 잘못된 값을 가질 수없는 경우 첫 번째 표현식을 두 번째 표현식으로 바꿀 수 있습니다.
상황에 따라 다릅니다.
나는 일종의 컬렉션이 될 if A:
것으로 기대할 때 사용 A
하며 컬렉션이 비어 있지 않은 경우에만 블록을 실행하고 싶습니다. 이렇게하면 호출자가 비어 있거나없는 잘 동작하는 컬렉션을 전달하고 예상 한대로 수행 할 수 있습니다. 또한 코드 실행에 편리한 블록 실행을 허용 None
및 False
억제합니다.
OTOH, 내가 기대한다면 A
어떤 완전히 임의의 객체 수 있지만,이 디폴트로 수 있었던 None
그때, 항상 사용하는 if A is not None
코드를 호출하면 의도적으로 빈 수집, 빈 문자열 또는 0 값 숫자 형식에 대한 참조를 통과 한 수로, 또는 boolean False
또는 boolean 컨텍스트에서 false 인 클래스 인스턴스.
그리고 다른 한편으로, A
좀 더 구체적인 것 (예 : 클래스를 호출 할 클래스의 인스턴스)이 될 것으로 예상 되지만 기본값으로 설정되었을 수 있으며 None
기본 부울 변환은 클래스의 속성 모든 하위 클래스에 적용하는 것을 신경 쓰지 않으면 if A:
손가락을 추가로 12 자 입력하는 끔찍한 부담을 덜기 위해 사용 합니다.
라는 파일을 작성 test.py
하여 통역사에서 실행했습니다. 장면 뒤에서 상황이 어떻게 진행되고 있는지 테스트하기 위해 원하는 것을 변경할 수 있습니다.
import dis
def func1():
matchesIterator = None
if matchesIterator:
print( "On if." );
def func2():
matchesIterator = None
if matchesIterator is not None:
print( "On if." );
print( "\nFunction 1" );
dis.dis(func1)
print( "\nFunction 2" );
dis.dis(func2)
이것이 어셈블러 차이점입니다.
출처:
>>> import importlib
>>> reload( test )
Function 1
6 0 LOAD_CONST 0 (None)
3 STORE_FAST 0 (matchesIterator)
8 6 LOAD_FAST 0 (matchesIterator)
9 POP_JUMP_IF_FALSE 20
10 12 LOAD_CONST 1 ('On if.')
15 PRINT_ITEM
16 PRINT_NEWLINE
17 JUMP_FORWARD 0 (to 20)
>> 20 LOAD_CONST 0 (None)
23 RETURN_VALUE
Function 2
14 0 LOAD_CONST 0 (None)
3 STORE_FAST 0 (matchesIterator)
16 6 LOAD_FAST 0 (matchesIterator)
9 LOAD_CONST 0 (None)
12 COMPARE_OP 9 (is not)
15 POP_JUMP_IF_FALSE 26
18 18 LOAD_CONST 1 ('On if.')
21 PRINT_ITEM
22 PRINT_NEWLINE
23 JUMP_FORWARD 0 (to 26)
>> 26 LOAD_CONST 0 (None)
29 RETURN_VALUE
<module 'test' from 'test.py'>
파이썬> = 2.6,
우리가 다음과 같이 쓰면
if A:
다음과 같이 경고를 생성합니다.
FutureWarning :이 방법의 동작은 다음 버전에서 변경 될 것입니다. 대신 특정 'len (elem)'또는 'elem is not None'테스트를 사용하십시오.
그래서 우리는 사용할 수 있습니다
if A is not None:
A is not None
할 일이 많이 적은 작업이 있기 때문에 빠른