在Python中,当我在hasattr装饰器上调用@property时,hasattr函数实际上运行@property代码块。
例如:一门课:
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的情况下解决这个问题?
发布于 2015-05-09 19:12:44
hasattr()通过实际检索属性来工作;如果抛出异常,hasattr()将返回False。这是因为这是了解属性是否存在的唯一可靠方法,因为在Python (__getattr__、__getattribute__、property对象、元类等)上注入属性的动态方法太多了。
这是通过调用
getattr(object, name)并查看它是否引发异常来实现的。
如果不希望在执行此操作时调用属性,则不要使用hasattr。使用vars() (返回实例字典)或dir() (也给出类上的名称列表)。
发布于 2015-05-09 19:15:26
hasattr基本上是这样实现的(除了在C中):
def hasattr(obj, attrname):
try:
getattr(obj, attname)
except AttributeError:
return False
return True因此,在真正的“请求宽恕比请求许可”(EAFP)的方式中,要确定对象是否具有给定的属性,Python只需尝试获取属性,并将失败转换为False的返回值。由于它在成功案例中真正获得了属性,hasattr()可以为property和其他描述符触发代码。
要在不触发描述符的情况下检查属性,可以编写自己的hasattr,遍历对象的方法解析顺序,并检查名称是否在每个类的__dict__ (或__slots__)中。因为这不是属性访问,所以不会触发属性。
方便地,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)注意,如果我们不能在hasattr()中找到所需的名称,那么我们就回到使用dir(),因为dir()将找不到动态属性(即__getattr__被覆盖的位置)。当然,这些代码仍然会被触发,所以如果您不关心找不到它们,就可以省略or子句。
总的来说,这是浪费的,因为当我们只关心某个特定属性是否存在时,它就会得到所有相关的属性名称,但在紧要关头就可以了。我甚至不确定自己执行循环(而不是调用dir() )是否平均速度更快,因为它使用的是Python而不是C。
发布于 2016-10-16 18:25:26
把变量作为类变量,然后调用hasattr,这对我起了很大作用。
if not hasattr(google_plus_user, GooglePlusUser.call):
self.response.out.write('Unknown call')
returnhttps://stackoverflow.com/questions/30143957
复制相似问题