Python 为什么hasattr执行@property decorator代码块
在Python中,当我对Python 为什么hasattr执行@property decorator代码块,python,python-2.7,properties,Python,Python 2.7,Properties,在Python中,当我对@property装饰程序调用hasattr时,hasattr函数实际上运行@property代码块 例如,a类: class GooglePlusUser(object): def __init__(self, master): self.master = master def get_user_id(self): return self.master.google_plus_service.people().get(
@property
装饰程序调用hasattr
时,hasattr
函数实际上运行@property
代码块
例如,a类:
class GooglePlusUser(object):
def __init__(self, master):
self.master = master
def get_user_id(self):
return self.master.google_plus_service.people().get(userId='me').execute()['id']
@property
def profile(self):
# this runs with hasattr
return self.master.google_plus_service.people().get(userId='me').execute()
运行以下代码将调用profile属性并实际进行调用:
#Check if the call is an attribute
if not hasattr(google_plus_user, call):
self.response.out.write('Unknown call')
return
为什么??我如何在不调用api的情况下解决这个问题 hasattr()
通过实际检索属性来工作;如果抛出异常hasattr()
将返回False
。这是因为这是知道属性是否存在的唯一可靠方法,因为有很多动态方法可以在Python对象上注入属性(\uuu getattr\uuu
,\uu getattribute\uuu
,属性
对象,元类等)
从:
这是通过调用getattr(object,name)
并查看它是否引发异常来实现的
如果不希望在执行此操作时调用属性,则不要使用
hasattr
。使用vars()
因此,在真正的“请求原谅比请求许可更容易”(EAFP)方式中,为了确定对象是否具有给定的属性,Python只是尝试获取该属性,并将失败转换为返回值False
。由于它在成功案例中真正获得了属性,hasattr()
可以触发属性
和其他描述符的代码
要在不触发描述符的情况下检查属性,您可以编写自己的hasattr
,遍历对象的方法解析顺序,并检查名称是否位于每个类的\uuuuu dict\uuu
(或\uu slots\uuu
)中。因为这不是属性访问,所以不会触发属性
方便的是,Python已经有了一种方法来遍历方法解析顺序并从实例类中收集属性名称:dir()
。那么,编写这种方法的简单方法是:
# gingerly test whether an attribute exists, avoiding triggering descriptor code
def gentle_hasattr(obj, name):
return name in dir(obj) or hasattr(obj, name)
请注意,如果在dir()
中找不到所需的名称,我们将返回使用hasattr()
,因为dir()
将找不到动态属性(即,\uuu getattr\uuuu
被覆盖的位置)。当然,这些代码仍然会被触发,因此如果您不介意找不到它们,您可以省略或
子句
总的来说,这是浪费,因为当我们只关心某个特定的属性是否存在时,它会获取所有相关的属性名称,但在必要的时候它会这样做。我甚至不确定自己执行循环而不是调用dir()
平均速度会更快,因为它将在Python中而不是在C中。将变量作为类变量,然后对其调用hasattr对我来说很有帮助
if not hasattr(google_plus_user, GooglePlusUser.call):
self.response.out.write('Unknown call')
return
使用了dir
,这对我来说很管用。再次感谢Martijn。需要注意的重要一点是:如果抛出任何异常,它会得出结论说它没有attr。@felix:只有在Python 2中,只有在Python 3中AttributeError
才会导致hasattr()
返回False
。其他异常会被传播。更好的是,尽管在该方法调用中的任何地方引发的任何AttributeError都会这样做。我刚刚修复了一个发生数据库调用的问题,因为我错误地认为我可以使用hasattr
@felix进行对象特性测试:是的,任何AttributeError
都会这样做,因为无法区分故意和意外的属性错误。起初我不相信这一点,但这是真的。如果attrname
指定了一个引发AttributeError
hasattr
的属性,则会令人困惑地返回False
。
if not hasattr(google_plus_user, GooglePlusUser.call):
self.response.out.write('Unknown call')
return