Как проверить, существует ли переменная?
Я хочу проверить, существует ли переменная. Сейчас я делаю что-то вроде этого:
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')
надеюсь это поможет!