Jim*_*ane 6 python properties python-2.7
在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()
Run Code Online (Sandbox Code Playgroud)
运行以下代码调用profile属性并实际进行调用:
#Check if the call is an attribute
if not hasattr(google_plus_user, call):
self.response.out.write('Unknown call')
return
Run Code Online (Sandbox Code Playgroud)
为什么?如何在不拨打api电话的情况下解决这个问题?
Mar*_*ers 11
hasattr()通过实际检索属性来工作 ; 如果抛出异常hasattr()返回False.这是因为这是知道,如果一个属性存在的唯一可靠的方法,因为有这么多动态的方式注入于Python对象(属性__getattr__,__getattribute__,property对象,元类等).
这是通过调用
getattr(object, name)和查看它是否引发异常来实现的.
如果您不希望在执行此操作时调用属性,请不要使用hasattr.使用vars()(返回实例字典)或dir()(它也为您提供类的名称列表).
hasattr 基本上是这样实现的(除了在 C 中):
def hasattr(obj, attrname):
try:
getattr(obj, attname)
except AttributeError:
return False
return True
Run Code Online (Sandbox Code Playgroud)
因此,在真正的“请求宽恕比许可更容易”(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)
Run Code Online (Sandbox Code Playgroud)
请注意,hasattr()如果在 中找不到所需的名称,我们将回退到使用dir(),因为dir()找不到动态属性(即 where__getattr__被覆盖)。当然,这些代码仍然会被触发,因此如果您不在乎找不到它们,则可以省略该or子句。
总而言之,这是一种浪费,因为当我们只对特定的属性名称是否存在感兴趣时,它会获取所有相关的属性名称,但它会在紧要关头完成。我什至不确定自己执行循环而不是调用dir()平均会更快,因为它将使用 Python 而不是 C。
| 归档时间: |
|
| 查看次数: |
1762 次 |
| 最近记录: |