проверка - python пустая переменная




нулевой объект в Python? (4)

None , Python null?

В Python нет null , вместо этого есть None . Как уже было сказано, наиболее точный способ проверить, что что-то было дано None поскольку значение заключается в использовании оператора идентификации, который проверяет, что две переменные относятся к одному и тому же объекту.

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

Основы

Существует и может быть только один None

None является единственным экземпляром класса NoneType и любые дальнейшие попытки создания экземпляра этого класса возвратят тот же объект, что делает None singleton. Новички на Python часто видят сообщения об ошибках, которые упоминают NoneType и задаются вопросом, что это такое. Мое личное мнение о том, что эти сообщения могут просто упоминать « None по имени», потому что, как мы вскоре увидим, None оставляет мало места для двусмысленности. Поэтому, если вы видите сообщение NoneType котором упоминается, что NoneType не может это сделать или не может этого сделать, просто знайте, что это просто тот, который использовался не таким образом, каким он не может.

Кроме того, None - это встроенная константа, как только вы запускаете Python, ее можно использовать везде, будь то в модуле, классе или функции. NoneType , напротив, нет, вам нужно сначала получить ссылку на него, запросив None для своего класса.

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

Вы можете проверить уникальность None с идентификационной функцией Python 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 одинаковы. Нет «обычай» « 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==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 - это «ложь», означающая, что при использовании в boolean оно вернет False и если применяется not оператор, он вернет True . Обратите внимание, однако, что это не свойство, уникальное для None . В дополнение к самому False свойство делится пустым списком, кортежами, наборами, dicts, строками, а также 0 и всеми объектами из классов, которые реализуют магический метод __bool__() для возврата 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 , или пустая строка, или пустой список, также должно инициировать инициализацию. Как я уже сказал, будьте внимательны. Как это часто бывает в ядре Python, это лучше, чем неявное .

None на практике

None используется в качестве значения сигнала

None имеет специального статуса в Python. Это любимое базовое значение, потому что многие алгоритмы рассматривают его как исключительную ценность. В таких сценариях он может использоваться как флаг, чтобы сигнализировать, что условие требует некоторой специальной обработки (например, значение по умолчанию).

Вы можете назначить 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

Если вы попытаетесь получить к нему доступ, используя нотацию 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'] или если он просто установлен в None . Если вам нужна эта информация, обычным способом справиться с этим является попытка прямого доступа к атрибуту или ключу из конструкции try/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)

В приведенных выше двух примерах показано, как обрабатывать случаи объектов и словарей, а также о функциях? То же самое, но мы используем аргумент ключевого слова double asterisks для этой цели:

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 , просто чтобы различать флаги None данные None , просто используйте другое тестовое значение. Существует шаблон, в котором значение, выходящее за пределы допустимых значений, вставляется как часть данных в структуру данных и используется для контроля и тестирования особых условий (например, границ, состояний и т. Д.). Такое значение называется дозорным, и его можно использовать так, как в качестве сигнала используется None . Тривиально создавать часового в Python.

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

С dict

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 , поэтому python не защищает их. Вы можете перезаписать свое undefined выше в любое время, в любом месте модуля, который он определен, поэтому будьте осторожны, как вы их открываете и используете. Затем экземпляр, возвращаемый object() , не является одиночным, если вы вызываете этот вызов в 10 раз, вы получаете 10 разных объектов. Наконец, использование дозорного врача очень своеобразно. Часовое относится к библиотеке, в которой она используется, и поэтому ее область действия должна быть ограничена внутренними библиотеками. Он не должен «течь». Внешний код должен только осознавать это, если их целью является расширение или дополнение API библиотеки.

Как я могу ссылаться на нулевой объект в Python?


В Python для представления отсутствия значения вы можете использовать значение None ( types.NoneType.None ) для объектов и «» (или len () == 0 ) для строк. Следовательно:

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

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

Что касается разницы между «==» и «is», проверка наличия идентификатора объекта с использованием «==» должна быть достаточной. Однако, поскольку операция «есть» определяется как операция идентификации объекта, вероятно, правильнее использовать ее, а не «==». Не уверен, есть ли разница в скорости.

В любом случае, вы можете посмотреть:



В Python объект «null» - это singleton None .

Лучшим способом проверить вещи для «Ненецкого» является использование оператора идентификации:

if foo is None:
    ...






null