如何检查变量是否存在?

2024-12-06 08:39:00
admin
原创
149
摘要:问题描述:我想检查一个变量是否存在。现在我正在做这样的事情:try: myVar except NameError: # Do something. 还有其他没有例外的方法吗?解决方案 1:检查局部变量是否存在:if 'myVar' in locals(): # myVar exists....

问题描述:

我想检查一个变量是否存在。现在我正在做这样的事情:

try:
    myVar
except NameError:
    # Do something.

还有其他没有例外的方法吗?


解决方案 1:

检查局部变量是否存在:

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

检查全局变量是否存在:

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

检查对象是否具有属性:

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

解决方案 2:

使用尚未定义或设置(隐式或显式)的变量通常是一件坏事,因为它往往表明程序的逻辑不一定经过完全考虑,并且可能会导致不可预测的行为。

如果您确实需要在 Python 中执行此操作,则以下与您的技巧类似的技巧将确保变量在使用前具有某些值:

try:
    myVar
except NameError:
    myVar = None      # or some other default value.

# Now you're free to use myVar without Python complaining.

当然,您选择赋予它的值取决于您在这种情况下想要做什么。例如,如果它是某个累加器的起始值,您可以将其设置为零。


但是(这是我的观点),重构代码可能会更好,这样就不会发生这种情况。

举例来说,下面的代码对此答案进行了注释,以允许从前一个点到当前点画线:

if last:
    draw(last, current);
last = current

如果 wherelast尚未绑定到值,那么在 Python 中这根本无济于事,因为即使检查也会引发last异常。更好的想法是确保last 确实有一个值,该值可用于确定它是否有效。这将是这样的:

last = None

# some time passes ...

if last is not None:
    draw(last, current);
last = current

这确保变量存在,并且只有当它对于您需要它有效时才使用它。

您仍然可以使用上面给出的异常方法添加代码来强制执行此操作(如果您无法控制变量的初始设置):

# Variable 'last' may or may not be bound to a value at this point.

try:
    last
except NameError:
    last = None

# It will always now be bound to a value at this point.

if last is not None:
    draw(last, current);
last = current

解决方案 3:

一个简单的方法是首先初始化它myVar = None

然后后来:

if myVar is not None:
    # Do something

解决方案 4:

对于对象/模块,您还可以

'var' in dir(obj)

例如,

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

解决方案 5:

使用 try/except 是测试变量是否存在的最佳方法。但几乎可以肯定,无论你做什么,都有比设置/测试全局变量更好的方法。

例如,如果您想在第一次调用某个函数时初始化模块级变量,那么最好使用如下代码:

my_variable = None

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

解决方案 6:

我将假设测试将在函数中使用,类似于user97370 的答案。我不喜欢这个答案,因为它污染了全局命名空间。修复它的一种方法是改用类:

class InitMyVariable(object):
  my_variable = None

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

我不喜欢这样,因为它使代码复杂化,并引发了一些问题,例如,这是否应该符合单例编程模式?幸运的是,Python 允许函数具有属性,这为我们提供了这个简单的解决方案:

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

解决方案 7:

catch在 Python 中调用except。除此之外,对于这种简单的情况来说,它就足够了。有一个AttributeError可以用来检查对象是否具有属性的。

解决方案 8:

我创建了一个自定义函数。

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

然后调用如下函数,替换variable_name您想要检查的变量:

exists("variable_name")

将返回TrueFalse

要检查 Python 中局部范围内是否存在变量,可以使用该locals()函数,该函数返回包含所有局部变量的字典。您可以修改exists函数以检查全局和局部范围,如下所示:

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

你可以通过以下方法检查局部范围内的变量是否存在:

def my_function():
    local_var = 42
    print(exists('local_var'))

my_function()  # Output: True
print(exists('local_var'))  # Output: False

在上面的例子中,because中的exists('local_var')returns是在函数内部本地定义的。但是,它在函数外部返回,因为在全局范围内不可访问。True`my_functionlocal_varFalse`local_var

解决方案 9:

处理这种情况的一种常用方法是不明确检查变量是否存在,而是直接将可能不存在的变量的第一次使用包装在 try/except 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
  ...

解决方案 10:

就像这样:

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: 

解决方案 11:

它可能性能不佳,但您可以将解决方案推广到检查局部变量和全局变量的函数。

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')

解决方案 12:

简短版本:

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

解决方案 13:

这是我的情况:

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

我无法轻易确定可迭代对象的长度,这意味着i可能存在或不存在取决于可迭代对象是否产生空序列。

如果我想使用i可迭代对象的最后一个(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是最后一个元素。 在这方面,第二个解决方案更准确。

解决方案 14:

对于对象来说也是一种可能性,使用__dict__

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

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

解决方案 15:

简单一行:

a=1
exec("try: a 
except NameError: print('Does not exist.')
else:print(a)")

并做一些事情:

exec("def my_try(): 
    try: a 
    except NameError: print('Does not exist.Creating a=');a=1;print(a);
    else:print(a)


my_try()")

解决方案 16:

嗯。我只是像这样简单地包装变量:

globals().get('myVar', <non-existant-value>)

或者 ...

locals().get('myVar', <non-existant-value>)

根据范围,<non-existant-value>您知道会超出范围的东西在哪里,例如NoneFalse。这适用于我遇到的 99% 的情况。始终避免过度设计的诱惑。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2577  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1553  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   26  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   21  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   18  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用