Как проверить, существует ли переменная?

Я хочу проверить, существует ли переменная. Сейчас я делаю что-то вроде этого:

try:
   myVar
except NameError:
   # Do something.

Есть ли другие способы без исключений?

17 ответов

Решение

Чтобы проверить существование локальной переменной:

if 'myVar' in locals():
  # myVar exists.

Чтобы проверить существование глобальной переменной:

if 'myVar' in globals():
  # myVar exists.

Чтобы проверить, есть ли у объекта атрибут:

if hasattr(obj, 'attr_name'):
  # obj.attr_name exists.

Использование переменных, которые не были определены или установлены (неявно или явно), почти всегда плохо на любом языке, поскольку это указывает на то, что логика программы не была продумана должным образом и может привести к непредсказуемым последствиям. поведение.

Следующий трюк, аналогичный вашему, гарантирует, что переменная имеет какое-либо значение перед использованием:

try:
    myVar
except NameError:
    myVar = None
# Now you're free to use myVar without Python complaining.

Тем не менее, я все еще не думаю, что это хорошая идея - по моему мнению, вы должны реорганизовать свой код, чтобы такая ситуация не возникала.

Простой способ - сначала инициализировать его, сказав myVar = None

Потом позже:

if myVar is not None:
    # Do something

Использование try/ исключением - лучший способ проверить существование переменной. Но почти наверняка есть лучший способ сделать то, что вы делаете, чем устанавливать / тестировать глобальные переменные.

Например, если вы хотите инициализировать переменную уровня модуля при первом вызове некоторой функции, вам лучше использовать код, подобный следующему:

my_variable = None

def InitMyVariable():
  global my_variable
  if my_variable is None:
    my_variable = ...

Для объектов / модулей вы также можете

'var' in dir(obj)

Например,

>>> class Something(object):
...     pass
...
>>> c = Something()
>>> c.a = 1
>>> 'a' in dir(c)
True
>>> 'b' in dir(c)
False

Я предполагаю, что тест будет использоваться в функции, аналогичной ответу пользователя 97370. Мне не нравится этот ответ, потому что он загрязняет глобальное пространство имен. Один из способов исправить это - использовать класс:

class InitMyVariable(object):
  my_variable = None

def __call__(self):
  if self.my_variable is None:
   self.my_variable = ...

Мне это не нравится, потому что это усложняет код и открывает такие вопросы, как, должно ли это подтвердить шаблон программирования Singleton? К счастью, Python позволил функциям некоторое время иметь атрибуты, что дает нам простое решение:

def InitMyVariable():
  if InitMyVariable.my_variable is None:
    InitMyVariable.my_variable = ...
InitMyVariable.my_variable = None

catch называется except в Python. кроме этого это хорошо для таких простых случаев. Там есть AttributeError это может использоваться, чтобы проверить, есть ли у объекта атрибут.

Я создал кастомную функцию.

def exists(var):
     return var in globals()

Затем вызовите функцию, подобную следующей, заменив variable_name с переменной, которую вы хотите проверить:

exists("variable_name")

Вернусь True или False

Способ, который часто работает хорошо для обработки такой ситуации, состоит в том, чтобы не явно проверять, существует ли переменная, а просто пойти дальше и обернуть первое использование, возможно, несуществующей переменной, в try/ кроме NameError:

# Search for entry.
for x in y:
  if x == 3:
    found = x

# Work with found entry.
try:
  print('Found: {0}'.format(found))
except NameError:
  print('Not found')
else:
  # Handle rest of Found case here
  ...

Это просто дополнение к предыдущим ответам, чтобы проверить, присутствует ли ключ в JSON/Dict или нет в python

"Имя объекта Json/Dict".has_key("имя ключа")

это вернет True или False

Вот так:

      def no(var):
    "give var as a string (quote it like 'var')"
    assert(var not in vars())
    assert(var not in globals())
    assert(var not in vars(__builtins__))
    import keyword
    assert(var not in keyword.kwlist)

Тогда позже:

      no('foo')
foo = ....

Если ваша новая переменная foo небезопасно использовать, вы получите AssertionErrorисключение, которое будет указывать на строку, в которой произошел сбой, и тогда вам будет лучше. Вот очевидная надуманная ссылка на себя:

      no('no')

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-88-d14ecc6b025a> in <module>
----> 1 no('no')

<ipython-input-86-888a9df72be0> in no(var)
      2     "give var as a string (quote it)"
      3     assert( var not in vars())
----> 4     assert( var not in globals())
      5     assert( var not in vars(__builtins__))
      6     import keyword

AssertionError: 

Это может быть неэффективным, но вы обобщаете решение до функции, которая проверяет как локальные, так и глобальные переменные.

      import inspect
def exists_var(var_name):
    frame = inspect.currentframe()
    try:
        return var_name in frame.f_back.f_locals or var_name in globals()
    finally:
        del frame

Тогда вы можете использовать это так:

      exists_var('myVar')

Краткий вариант:

my_var = some_value if 'my_var' not in globals() else my_var:

Также возможность для объектов, используйте __dict__.

      class A(object):
    def __init__(self):
        self.m = 1

a = A()
assert "m" in a.__dict__
assert "k" not in a.__dict__

Это был мой сценарий:

for i in generate_numbers():
    do_something(i)
# Use the last i.

Я не могу легко определить длину итерации, а это значит, что i может существовать или не существовать в зависимости от того, производит ли итерация пустую последовательность.

Если я хочу использовать последний i итерируемого (an i которого не существует для пустой последовательности) Я могу сделать одно из двух:

i = None  # Declare the variable.
for i in generate_numbers():
    do_something(i)
use_last(i)

или же

for i in generate_numbers():
    do_something(i)
try:
    use_last(i)
except UnboundLocalError:
    pass  # i didn’t exist because sequence was empty.

Первое решение может быть проблематичным, потому что я не могу сказать (в зависимости от значений последовательности), iбыл последним элементом. Второе решение в этом отношении более точное.

Простая одна строка:

      a=1
exec("try: a \nexcept NameError: print('Does not exist.')\nelse:print(a)")

и сделать что-нибудь:

      exec("def my_try(): \n\ttry: a \n\texcept NameError: print('Does not exist.Creating a=');a=1;print(a);\n\telse:print(a)\n\n\nmy_try()")

Попробуйте:`

Myvariable = ['v', 'a', 'r']
try:
    print(Myvariable)
except Nameerror:
    print('variable \"Myvariable\" not found')

надеюсь это поможет!

Другие вопросы по тегам