如何可靠地检查 Python 属性 是否存在?
How to robustly check a Python property exists?
给定以下 class(有一个 buggy 属性)那么检查 bar
属性 是否存在的最佳万无一失的方法是什么?
class Foo(object):
@property
def bar(self):
raise AttributeError('unforeseen attribute error!')
hasattr
和 getattr
都失败了,只有 dir
有效:
foo = Foo()
print hasattr(foo, 'bar')
# False
try:
getattr(foo, 'bar')
print True
except AttributeError as e:
print False
# False
print 'bar' in dir(foo)
# True
我能想到的最好的全面解决方案是:
def robust_hasattr(obj, attr):
return hasattr(obj, attr) or attr in dir(obj)
有没有更好的方法?
如果您有错误 属性,修复错误。如果提高 AttributeError
是一个错误,那么让 属性 不这样做。引发该异常是 表示您不应使用该属性的方式。
使用 dir()
可能是一种解决方法,但它是 not foolproof, as dir()
is a debugging aid that can both omit information and can be overridden by the object.__dir__
hook (giving your code another vector to introduce bugs). Then there is the possibility of a buggy object.__getattr__
hook, a buggy object.__getattribute__
hook,甚至是元 class 上的描述符,所有这些都无法通过使用 dir()
.
由于您专门寻找 属性,请在对象的 class 上寻找相同的属性:
hasattr(foo, 'bar') or isinstance(getattr(type(foo), 'bar', None), property)
对于您的具体情况,上述 returns 正确:
>>> class Foo(object):
... @property
... def bar(self):
... raise AttributeError('unforeseen attribute error!')
...
>>> foo = Foo()
>>> hasattr(foo, 'bar') or isinstance(getattr(type(foo), 'bar', None), property)
True
因为class上确实有这样一个property
对象。
根据 Python 的规则,bar
属性 不存在 。如果访问属性的尝试没有引发异常,则认为对象具有属性。
如果您想对属性是否存在使用不同的概念,您可以自己实现该概念。例如,要检查实例字典中是否存在对应于 bar
或 class 字典之一的条目:
for obj in (foo,) + type(foo).__mro__:
if 'bar' in obj.__dict__:
print "It's there."
break
else:
print "Didn't find it."
给定以下 class(有一个 buggy 属性)那么检查 bar
属性 是否存在的最佳万无一失的方法是什么?
class Foo(object):
@property
def bar(self):
raise AttributeError('unforeseen attribute error!')
hasattr
和 getattr
都失败了,只有 dir
有效:
foo = Foo()
print hasattr(foo, 'bar')
# False
try:
getattr(foo, 'bar')
print True
except AttributeError as e:
print False
# False
print 'bar' in dir(foo)
# True
我能想到的最好的全面解决方案是:
def robust_hasattr(obj, attr):
return hasattr(obj, attr) or attr in dir(obj)
有没有更好的方法?
如果您有错误 属性,修复错误。如果提高 AttributeError
是一个错误,那么让 属性 不这样做。引发该异常是 表示您不应使用该属性的方式。
使用 dir()
可能是一种解决方法,但它是 not foolproof, as dir()
is a debugging aid that can both omit information and can be overridden by the object.__dir__
hook (giving your code another vector to introduce bugs). Then there is the possibility of a buggy object.__getattr__
hook, a buggy object.__getattribute__
hook,甚至是元 class 上的描述符,所有这些都无法通过使用 dir()
.
由于您专门寻找 属性,请在对象的 class 上寻找相同的属性:
hasattr(foo, 'bar') or isinstance(getattr(type(foo), 'bar', None), property)
对于您的具体情况,上述 returns 正确:
>>> class Foo(object):
... @property
... def bar(self):
... raise AttributeError('unforeseen attribute error!')
...
>>> foo = Foo()
>>> hasattr(foo, 'bar') or isinstance(getattr(type(foo), 'bar', None), property)
True
因为class上确实有这样一个property
对象。
根据 Python 的规则,bar
属性 不存在 。如果访问属性的尝试没有引发异常,则认为对象具有属性。
如果您想对属性是否存在使用不同的概念,您可以自己实现该概念。例如,要检查实例字典中是否存在对应于 bar
或 class 字典之一的条目:
for obj in (foo,) + type(foo).__mro__:
if 'bar' in obj.__dict__:
print "It's there."
break
else:
print "Didn't find it."