2009-10-20 2 views
270

Possible Duplicate:
Easy way to check that variable is defined in python?
How do I check if a variable exists in Python?Определить, если переменная определена в Python

Как вы знаете, является ли переменная установлена ​​в определенном месте в коде во время выполнения? Это не всегда очевидно, потому что (1) переменная может быть условно установлена, и (2) переменная может быть условно удалена. Я ищу что-то вроде defined() в Perl или isset() в PHP или defined? в Ruby.

if condition: 
    a = 42 

# is "a" defined here? 

if other_condition: 
    del a 

# is "a" defined here? 
+9

Дубликаты: http://stackoverflow.com/questions/843277/python-checking-variable-existing, http://stackoverflow.com/questions/750298/easy-way-to-check-that-variable-is -defined-in-python, – carl

+54

Пожалуйста, пожалуйста, не «условно» установить переменную. Это просто ужасный, ужасный дизайн. Всегда, всегда, всегда обеспечивайте все логические пути. Пожалуйста, не продолжайте это делать. –

+1

+1 к S.Lott anwser. Тот факт, что есть способ сделать это, не означает, что вы должны использовать его в новом проекте. –

ответ

451
try: 
    thevariable 
except NameError: 
    print "well, it WASN'T defined after all!" 
else: 
    print "sure, it was defined." 
+66

@Aaron: Есть много случаев, когда вы не знаете, определена ли переменная. Вы можете использовать код рефакторинга, чтобы избежать этого во многих, но не во всех случаях. Решение Alex является правильным, и это лучше, если по некоторым причинам рефакторинг невозможен. В вопросе не так много информации, поэтому я считаю, что только человек спросил, что он может выбрать лучший способ справиться со своим делом. –

+124

@Aaron, "should" - это 4-буквенное слово - например. ни один водитель «не должен» превышать ограничение скорости, но это не означает, что вы не принимаете все надлежащие и необходимые меры предосторожности против тех, кто все же это делает. Поддержание хрупкого, заложенного унаследованного кода с несколько разрушенным дизайном, который вы унаследовали от кого-то другого, - это факт жизни, и те, кто может думать только о переполнении большого взрыва с нуля, а не осторожно и постепенно перечитывать 9-летние Джоэля -old эссе http://www.joelonsoftware.com/articles/fog0000000069.html. –

+10

@ S.Lott Люди используют его для обеспечения обратной совместимости. Найдите исходный код NameError в исходном коде Python 3.1. Существует много примеров, где используется «try: var_name, кроме NameError: something_else». Вот пара мест, где он используется: библиотека CSV (http://svn.python.org/projects/python/trunk/Lib/csv.py) и библиотека ElementTree (http: //svn.python. орг/проекты/питон/багажник/Lib/XML/etree/ElementTree.py). – sc45

11
try: 
    a # does a exist in the current namespace 
except NameError: 
    a = 10 # nope 
+5

Исключения должны использоваться только в исключительных случаях. См. [Это обсуждение] (http://stackoverflow.com/q/77127/1593077) – einpoklum

+10

@einpoklum Это верно для большинства языков, но в исключениях Python используются чаще, см., Например, http://stackoverflow.com/questions/3086806 – sdcvvc

+1

Хм, странно, но верно, видимо. Я все еще думаю, что это не хорошая идея (TM), но, ну, не может спорить с обычаями сообщества. – einpoklum

235

'a' in vars() or 'a' in globals()

, если вы хотите быть педантичным, вы можете проверить внутренние команды слишком
'a' in vars(__builtin__)

+17

Это должен быть ответ, на который я верю. см. http://stackoverflow.com/questions/843277/python-checking-variable-existing – 0atman

+1

Это очень идиоматический ответ. Для карт существует сильное применение; например, 'if" prop2 "в {" prop0 ": None," prop1 ": None}:' – robert

+0

Этот ответ также работает для обнаружения членов, отличных от переменных, таких как функции, классы и модули. – aaaantoine

91

Я думаю, что лучше, чтобы избежать ситуации. Это чище и понятнее написать:

a = None 
if condition: 
    a = 42 
+6

Если вам нравится делать это таким образом, вы должны сделать первоначальное значение уникальным, чтобы вы могли отличить от чего-то, задающего 'a'' 'None', т.е. 'UNDEFINED = object(); a = UNDEFINED', тогда вы можете проверить, что' a не НЕ УКАЗАННО' –

+11

Это обычное использование None. Это буквально семантический смысл Ничего - это ничего, нада, почтовый индекс. Он существует, но не имеет значения. Использование значения, отличного от None, полезно, если None может возникнуть в задании и т. Д., Но это не так часто, что избегать None должно быть стандартной практикой. Например, в вопросе a всегда будет 42 или неопределенным. Изменение неопределенного значения значения None приводит к потере информации. –

+3

Это путь, не уверенный, почему люди думают, используя конструкцию try/except LONG и DIRTY, чтобы это сделать. ТАКЖЕ это очень полезно при использовании ключевых слов args в функциях члена класса, где вы не хотите жестко кодировать значения по умолчанию в список параметров (вы просто определяете значение по умолчанию как член класса). – FizxMike

4

Для этого конкретного случая, что лучше делать a = None вместо del a. Это уменьшит счетчик ссылок на объект a был (если он есть) назначен и не сработает, если a не определен. Обратите внимание, что оператор del не вызывает деструктор объекта напрямую, но отвязывает его от переменной. Деструктор объекта вызывается, когда количество ссылок становится равным нулю.

4

Одним из возможных ситуаций, когда это может понадобиться:

Если вы используете finally блок для закрытия соединения, но в try блоке, программа завершается с sys.exit() до соединения определяется. В этом случае будет вызываться блок finally, и оператор закрытия соединения будет терпеть неудачу, поскольку соединение не было создано.

-2

Если кто-то хочет, чтобы поймать попытки получить доступ к не определенной переменной внутри объекта, есть очень простой способ сделать это:

class Whatever(object): 
    def __getattr__(self, key): 
    return None 

Здесь питон сначала пытается найти атрибут в объекте или дерева объектов, и только если это не выполняется, вызывается функция __getattr__(self, key). Это означает, что если __getattr__ называется, мы можем просто вернуть None.

+0

-1 '__getattr__' вызывается перед тем, как искать словарь. – quantum

+0

@ квант нет, это не так, но '__getattribute__' вызывается перед поиском словаря. –

 Смежные вопросы

  • Нет связанных вопросов^_^