首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么hasattr要执行@property装饰符代码块

为什么hasattr要执行@property装饰符代码块
EN

Stack Overflow用户
提问于 2015-05-09 19:09:01
回答 3查看 3.7K关注 0票数 13

在Python中,当我在hasattr装饰器上调用@property时,hasattr函数实际上运行@property代码块。

例如:一门课:

代码语言:javascript
复制
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属性并实际进行调用:

代码语言:javascript
复制
#Check if the call is an attribute
if not hasattr(google_plus_user, call):
    self.response.out.write('Unknown call')
    return

为什么?我如何在不调用api的情况下解决这个问题?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-09 19:12:44

hasattr()通过实际检索属性来工作;如果抛出异常,hasattr()将返回False。这是因为这是了解属性是否存在的唯一可靠方法,因为在Python (__getattr____getattribute__property对象、元类等)上注入属性的动态方法太多了。

来自 documentation

这是通过调用getattr(object, name)并查看它是否引发异常来实现的。

如果不希望在执行此操作时调用属性,则不要使用hasattr。使用vars() (返回实例字典)或dir() (也给出类上的名称列表)。

票数 17
EN

Stack Overflow用户

发布于 2015-05-09 19:15:26

hasattr基本上是这样实现的(除了在C中):

代码语言:javascript
复制
def hasattr(obj, attrname):
    try:
        getattr(obj, attname)
    except AttributeError:
        return False
    return True

因此,在真正的“请求宽恕比请求许可”(EAFP)的方式中,要确定对象是否具有给定的属性,Python只需尝试获取属性,并将失败转换为False的返回值。由于它在成功案例中真正获得了属性,hasattr()可以为property和其他描述符触发代码。

要在不触发描述符的情况下检查属性,可以编写自己的hasattr,遍历对象的方法解析顺序,并检查名称是否在每个类的__dict__ (或__slots__)中。因为这不是属性访问,所以不会触发属性。

方便地,Python已经有了一种方法来遍历方法的解析顺序,并从实例的类中收集属性的名称:dir()。因此,编写这种方法的一个简单方法是:

代码语言:javascript
复制
# 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。

票数 5
EN

Stack Overflow用户

发布于 2016-10-16 18:25:26

把变量作为类变量,然后调用hasattr,这对我起了很大作用。

代码语言:javascript
复制
if not hasattr(google_plus_user, GooglePlusUser.call):
  self.response.out.write('Unknown call')
  return
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30143957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档