파이썬에서 null 객체?


1192

파이썬에서 null 객체를 어떻게 참조합니까?

답변:


1628

파이썬에서 'null'객체는 singleton None입니다.

"없음"을 확인하는 가장 좋은 방법은 다음과 같이 ID 연산자를 사용하는 것입니다 is.

if foo is None:
    ...

125
그리고 선택에 대한 이유 egg is None이상 egg == None: 후자는 (당신을, 그것을 구현 어떻게에 따라 달라집니다,하지만 당신은 모든 사람이 계정에 없음으로 comparisions을 기대하지 않는다?) 과부하 및 없음 유효 개체를 비교했을 때 깰 가능성이 될 수있다 반면이 is항상 동일하게 작동합니다.

94
왜 파이썬 디자이너가 "null"을 선택하지 않았습니까? 그냥 달라야 하지마! ;)
Vidar

35
@Vidar 'None'은 객체가 부족하지 않으며 ( 'null'은 null 참조이므로) 실제 객체입니다. 'NoneType'이외의 다른 유형의 객체에 대해서는 'None'객체가 전달되지 않습니다. 또한 언어 개념도 아닙니다. 파이썬에 내장 된 언어가 아니며, 파이썬의 표준 라이브러리의 일부입니다. 없음! == (ahem) Null
Rushyo 2016

11
@ naught101 목적이 없다. 포인터의 개념이 없기 때문에. ctypes 라이브러리를 사용하는 경우 None은 주소 0의 동의어로 사용되지만 여전히 'null reference'라는 언어 개념은 없습니다. 파이썬에서는 객체가 없음 인 경우에도 항상 어떤 종류의 객체를 참조하는 것을 떠났습니다. 나는 이것이 언어를 크게 단순화 시킨다고 생각한다.
Rushyo

5
: 널 심판 인 '억 달러 실수'설명 훌륭한 프리젠 테이션 infoq.com/presentations/...을 . null 대신 다른 옵션은 Options 또는 Maybe (custom) 유형입니다.
Michael Trouw

133

None, 파이썬이 null입니까?

null파이썬 에는 없으며 대신에 있습니다 None. 이미 언급했듯이 None, 값 으로 주어진 것이 있는지 테스트하는 가장 정확한 방법 is은 두 개의 변수가 동일한 객체를 참조하는지 테스트하는 항등 연산자 를 사용하는 것입니다.

>>> foo is None
True
>>> foo = 'bar' 
>>> foo is None
False

기본

하나만있을 수 있습니다 None

None은 클래스의 유일한 인스턴스이며 해당 클래스 NoneType를 인스턴스화하려는 추가 시도는 동일한 객체를 반환하여 None싱글 톤 을 만듭니다 . 파이썬을 NoneType처음 접하는 사람들은 종종 그 내용이 무엇인지 궁금해하는 오류 메시지를 보게 됩니다. None우리가 곧 보게 되겠지만, None모호 할 여지가 거의 없기 때문에이 메시지들이 단순히 이름으로 만 언급 될 수 있다고 개인적으로 생각합니다 . 따라서이 작업을 수행 할 수 없거나 수행 할 수없는 TypeError메시지가 표시되면 해당 메시지가 NoneType단순히 None사용할 수없는 방식으로 사용되었다는 것만 알면 됩니다.

또한 None내장 상수이며, 파이썬을 시작하자마자 모듈, 클래스 또는 함수 등 어디서나 사용할 수 있습니다. NoneType반대로, None클래스 를 쿼리 하여 먼저 참조를 가져와야 합니다.

>>> NoneType
NameError: name 'NoneType' is not defined
>>> type(None)
NoneType

NonePython의 identity 함수를 사용하여 고유성을 확인할 수 있습니다 id(). 객체에 할당 된 고유 번호를 반환하며 각 객체에는 하나씩 있습니다. 두 변수의 id가 동일하면 실제로 동일한 객체를 가리 킵니다.

>>> NoneType = type(None)
>>> id(None)
10748000
>>> my_none = NoneType()
>>> id(my_none)
10748000
>>> another_none = NoneType()
>>> id(another_none)
10748000
>>> def function_that_does_nothing(): pass
>>> return_value = function_that_does_nothing()
>>> id(return_value)
10748000

None 덮어 쓸 수 없다

이전 버전의 Python (2.4 이전)에서는을 다시 할당 할 수 None있었지만 더 이상 할 수는 없었습니다. 클래스 속성이나 함수의 범위에도 없습니다.

# In Python 2.7
>>> class SomeClass(object):
...     def my_fnc(self):
...             self.None = 'foo'
SyntaxError: cannot assign to None
>>> def my_fnc():
        None = 'foo'
SyntaxError: cannot assign to None

# In Python 3.5
>>> class SomeClass:
...     def my_fnc(self):
...             self.None = 'foo'
SyntaxError: invalid syntax
>>> def my_fnc():
        None = 'foo'
SyntaxError: cannot assign to keyword

따라서 모든 None참조가 동일 하다고 가정하는 것이 안전합니다 . "custom"이 없습니다 None.

연산자 None사용 을 테스트하려면is

코드를 작성할 때 다음 과 같이 Noneness 를 테스트 하려는 유혹을받을 수 있습니다 .

if value==None:
    pass

또는 이와 같은 허위 테스트

if not value:
    pass

그 의미를 이해하고 왜 명시적인 것이 좋은 아이디어인지 이해해야합니다.

사례 1 : 가치가 있는지 테스트 None

왜 이러니

value is None

오히려

value==None

첫 번째는 다음과 같습니다.

id(value)==id(None)

표현 value==None은 실제로 다음과 같이 적용되는 반면

value.__eq__(None)

그 가치가 실제로 None라면 기대 한 것을 얻을 수 있습니다.

>>> nothing = function_that_does_nothing()
>>> nothing.__eq__(None)
True

대부분의 경우 결과는 동일하지만이 __eq__()메서드는 클래스에서 재정의되어 특별한 동작을 제공 할 수 있으므로 정확성을 보장하지 않는 문을 엽니 다.

이 수업을 고려하십시오.

>>> class Empty(object):
...     def __eq__(self, other):
...         return not other

그래서 당신은 그것을 시도 None하고 작동합니다

>>> empty = Empty()
>>> empty==None
True

그러나 빈 문자열에서도 작동합니다.

>>> empty==''
True

그리고 아직

>>> ''==None
False
>>> empty is None
False

사례 2 : None부울로 사용

다음 두 가지 테스트

if value:
    # do something

if not value:
    # do something

실제로 다음과 같이 평가됩니다

if bool(value):
    # do something

if not bool(value):
    # do something

None"falsey"는 부울로 캐스트하면 반환 False되고 적용되면 not연산자 가 반환됨을 의미합니다 True. 그러나이 속성은 고유 한 속성이 아닙니다 None. 그 False외에도이 속성은 빈 목록, 튜플, 집합, dict, 문자열 및 0과 __bool__()반환 할 magic 메서드를 구현하는 클래스의 모든 객체와 공유됩니다 False.

>>> bool(None)
False
>>> not None
True

>>> bool([])
False
>>> not []
True

>>> class MyFalsey(object):
...     def __bool__(self):
...         return False
>>> f = MyFalsey()
>>> bool(f)
False
>>> not f
True

따라서 다음과 같은 방법으로 변수를 테스트 할 때는 테스트에 포함하거나 제외 할 대상을 추가로 알고 있어야합니다.

def some_function(value=None):
    if not value:
        value = init_value()

위의 전화를 의미 했습니까 init_value() 의 값을 구체적으로 설정할 때None 했거나 값을 설정 0하거나 빈 문자열 또는 빈 목록도 초기화를 트리거해야 함을 의미 했습니까? 내가 말했듯이, 조심하십시오. 파이썬에서 종종 그렇듯이, explicit은 implicit보다 낫습니다 .

None 실제로

None 신호 값으로 사용

None파이썬에서 특별한 지위를 가지고 있습니다. 많은 알고리즘이이 값을 예외적 인 값으로 취급하기 때문에 선호하는 기본 값입니다. 이러한 시나리오에서는 조건에 일부 특수 처리 (예 : 기본값 설정)가 필요하다는 신호를 표시하는 플래그로 사용할 수 있습니다.

None함수의 키워드 인수에 할당 한 다음 명시 적으로 테스트 할 수 있습니다.

def my_function(value, param=None):
    if param is None:
        # do something outrageous!

객체의 속성을 얻으려고 할 때 기본값으로 반환 한 다음 특별한 것을하기 전에 명시 적으로 테스트 할 수 있습니다.

value = getattr(some_obj, 'some_attribute', None)
if value is None:
    # do something spectacular!

기본적 으로 존재하지 않는 키에 액세스하려고 하면 사전의 get()메소드가 반환 None됩니다.

>>> some_dict = {}
>>> value = some_dict.get('foo')
>>> value is None
True

A는 표기는 첨자를 사용하여 액세스하려고한다면 KeyError제기 될 것이다

>>> value = some_dict['foo']
KeyError: 'foo'

존재하지 않는 아이템을 팝하려고 할 때와 마찬가지로

>>> value = some_dict.pop('foo')
KeyError: 'foo'

일반적으로 설정된 기본값으로 억제 할 수 있습니다. None

value = some_dict.pop('foo', None)
if value is None:
    # booom!

None 플래그와 유효 값으로 사용

위에서 설명한 None적용은 유효한 값으로 간주되지 않지만 특별한 것을 수행하는 신호와 같은 경우 적용됩니다. 그러나 None신호로 사용 되더라도 데이터의 일부가 될 수 있기 때문에 어디에서 왔는지 알아야하는 경우 가 있습니다.

getattr(some_obj, 'attribute_name', None)되돌아 가면서 속성에 대해 객체를 쿼리 할 때 None액세스하려는 속성이 설정되어 None있는지 또는 객체에 전혀 없는지 여부는 알려주지 않습니다 . 과 같은 사전에서 키에 액세스 할 때와 동일한 상황에서 누락되었거나로 설정되어 있는지 some_dict.get('some_key')알 수 없습니다 . 해당 정보가 필요한 경우이를 처리하는 일반적인 방법은 구성 내에서 속성 또는 키에 직접 액세스하는 것입니다 .some_dict['some_key']Nonetry/except

try:
    # equivalent to getattr() without specifying a default
    # value = getattr(some_obj, 'some_attribute')
    value = some_obj.some_attribute
    # now you handle `None` the data here
    if value is None:
        # do something here because the attribute was set to None
except AttributeError:
    # we're now hanling the exceptional situation from here.
    # We could assign None as a default value if required.
    value = None 
    # In addition, since we now know that some_obj doesn't have the
    # attribute 'some_attribute' we could do something about that.
    log_something(some_obj)

dict과 마찬가지로 :

try:
    value = some_dict['some_key']
    if value is None:
        # do something here because 'some_key' is set to None
except KeyError:
    # set a default 
    value = None
    # and do something because 'some_key' was missing
    # from the dict.
    log_something(some_dict)

위의 두 예는 객체 및 사전 사례를 처리하는 방법을 보여줍니다. 함수는 어떻습니까? 똑같은 것이지만, 그 끝에 이중 별표 키워드 인수를 사용합니다.

def my_function(**kwargs):
    try:
        value = kwargs['some_key'] 
        if value is None:
            # do something because 'some_key' is explicitly 
            # set to None
    except KeyError:
        # we assign the default
        value = None
        # and since it's not coming from the caller.
        log_something('did not receive "some_key"')

None 유효한 값으로 만 사용

플래그와 데이터 try/except를 구별 하기 위해 코드가 위의 패턴으로 어지럽히면 다른 테스트 값을 사용하십시오. 유효한 값 집합을 벗어나는 값이 데이터 구조에서 데이터의 일부로 삽입되고 특수 조건 (예 : 경계, 상태 등)을 제어하고 테스트하는 데 사용되는 패턴이 있습니다. 이러한 값을 센티넬 이라고 하며 신호로 사용되는 방식 으로 사용할 수 있습니다 . 파이썬에서 센티넬을 만드는 것은 쉽지 않습니다.NoneNoneNone

undefined = object()

undefined위 의 객체는 독특하며 프로그램에 관심이있는 것을 많이하지 않으므로 다음을 대체 할 수있는 훌륭한 대안입니다.None 플래그로 있습니다. 일부 경고는 코드 이후에 적용됩니다.

기능으로

def my_function(value, param1=undefined, param2=undefined):
    if param1 is undefined:
        # we know nothing was passed to it, not even None
        log_something('param1 was missing')
        param1 = None


    if param2 is undefined:
        # we got nothing here either
        log_something('param2 was missing')
        param2 = None

받아쓰기

value = some_dict.get('some_key', undefined)
if value is None:
    log_something("'some_key' was set to None")

if value is undefined:
    # we know that the dict didn't have 'some_key'
    log_something("'some_key' was not set at all")
    value = None

대상으로

value = getattr(obj, 'some_attribute', undefined) 
if value is None:
    log_something("'obj.some_attribute' was set to None")
if value is undefined:
    # we know that there's no obj.some_attribute
    log_something("no 'some_attribute' set on obj")
    value = None

앞서 언급했듯이 맞춤 센티넬에는 몇 가지주의 사항이 있습니다. 첫째, 키워드는와 같은 키워드가 아니므로 None파이썬은 키워드를 보호하지 않습니다. undefined정의 된 모듈의 어느 곳에서나 언제든지 위의 내용을 덮어 쓸 수 있으므로 노출 및 사용 방법에주의하십시오. 다음으로 object()호출 된 인스턴스 는 싱글 톤이 아닙니다. 10 번 호출하면 10 개의 다른 객체가 생깁니다. 마지막으로, 센티넬의 사용은 매우 특이합니다. 센티넬은 사용되는 라이브러리에 따라 다르며 일반적으로 라이브러리의 내부로 범위가 제한되어야합니다. "누설"해서는 안됩니다. 라이브러리의 API를 확장하거나 보완하는 것이 목적인 경우 외부 코드는이를 인식해야합니다.


어떻습니까 : None == thing?
hkBst

@ hkBst 나는 당신의 질문이 파이썬이 평등을 어떻게 평가하는지에 관한 것 같아요. 이 stackoverflow.com/questions/3588776/…를보십시오
Michael Ekoka

아, 보통 IIUC는 여전히 물건을 부릅니다 .__ eq__? 이 경우 제안을 철회합니다.
hkBst

@MichaelEkoka이 인상적이고 유용한 정보의 출처를 공유 할 수 있습니다.
Anidhya Bhatnagar

표준 연습. 파이썬 튜토리얼을 통해 힌트를 얻을 수 있지만, 인기있는 프로젝트의 소스 코드를 읽는 것이 관용적 파이썬에 빠르게 빠져들게하는 가장 좋은 조언 입니다.
Michael Ekoka

67

다른 언어에서와 같이 null이라고 부르지는 않지만 None. 이 개체의 인스턴스는 항상 하나뿐이므로 원하는 경우 x is None대신 (신분 비교) 와 동일한 항목을 확인할 수 있습니다 x == None.


25
나는 re-instantiating하여 파이썬을 깨는 방법을 찾을 것 None입니다. 그렇다면 비교 한 모든 똑똑한 사람들 NoneType이 승리 할 것입니다!
Zenexer

28

Python에서는 값이 없음 을 나타 내기 위해 객체에 None 값 ( types.NoneType.None )을 사용하고 문자열에 "" (또는 len () == 0 )을 사용할 수 있습니다. 따라서:

if yourObject is None:  # if yourObject == None:
    ...

if yourString == "":  # if yourString.len() == 0:
    ...

"=="와 "is"의 차이점에 대해서는 "=="를 사용하여 객체 ID를 테스트하면 충분합니다. 그러나 "is"작업이 개체 ID 작업으로 정의되어 있으므로 "=="가 아니라 사용하는 것이 더 정확할 것입니다. 속도 차이가 있는지 확실하지 않습니다.

어쨌든, 당신은 볼 수 있습니다 :


8
내가 아는 한 (0 == false)는 모든 프로그래밍 언어에서 true를 반환합니다. false는 0이 아닌 모든 것으로 0과 "true"로 코딩되기 때문입니다. 그러나 "is"연산자가 "=="연산자와 같지 않아야합니다. 이것은 Java에서 "=="와 "equals"의 차이점이 거의 동일합니다. 연산자 "is"는 실제로 두 객체가 동일한 지 (같은 인스턴스가 아니라 동일한 내용이 아닌지) 확인합니다!
Paolo Rovelli

12
Paolo, FYI (0 == false)가 모든 프로그래밍 언어에서 true를 반환하지는 않습니다. 빠른 카운터 예제는 Scala입니다. 여기서 (0 == false)는 false를 반환하며, 숫자를 부울과 비교할 때 Scala가 false를 반환하는 유일한 프로그래밍 언어는 아니라고 확신합니다.
Rob Wilton

2
알았어! 그런 다음 대부분의 프로그래밍 언어로 말해 봅시다.
Paolo Rovelli

3
JavaScript에서 0 == false반환 되는 이유 는 true이중 같음 연산자가 강제 변환을 수행하기 때문입니다. 그러나 triple-equals 연산자를 사용하면 'number'와 'boolean'이 다른 유형이므로를 0 === false반환합니다 false.
jkdev

1
Lua, Ruby 및 Clojure의 @PaoloRovelli는 0이 true조건부 와 같이 취급됩니다 . 녹과 이동, 0그리고 false 어떤지를 비교 할 수없는 다른 유형입니다.
스쿠터 매달려

0

Null은 다음과 같은 특수한 객체 유형입니다.

>>>type(None)
<class 'NoneType'>

객체가 'NoneType'클래스에 있는지 확인할 수 있습니다.

>>>variable = None
>>>variable is None
True

자세한 내용은 Python Docs 에서 확인할 수 있습니다


-1

진리 값 테스트 간단한 표현이 충분하므로, '없음'직접 FALSE로 테스트하지 :

if not foo:

3
아뇨. 그 표현은 반환 True을 위해 어떤 아니라, falsy 값 None.
insert_name_here

사실, 간단한 "foo가 아닌 경우 :"는 명시된대로 원래 질문에 올바르게 대답하지 못합니다. 그러나 파이썬은 동적으로 유형이 지정되고 구문 프로토콜을 줄 이도록 초대하므로 더 단순하고 유사한 구성을 고려하는 것이 나에게 유효합니다.
artejera
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.