Python hasattr与getattr [英] Python hasattr vs getattr

查看:103
本文介绍了Python hasattr与getattr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在阅读一些 tweets 关于hasattr的python文档,其中说:

I have been reading lately some tweets and the python documentation about hasattr and it says:


hasattr(object,名称)

hasattr(object, name)


参数是一个对象和一个字符串。如果字符串是对象属性之一的名称>>,则结果为True,否则为False。 (这是通过调用
getattr(object,name)并查看它是否引发AttributeError来实现的。)


Python中有一个座右铭,那就是我通常会同意比许可更容易获得宽恕

There is a motto in Python that says that is Easier to ask for forgiveness than permission where I usually agree.

在这种情况下,我尝试使用一个非常简单的python代码进行性能测试:

I tried to do a performance test in this case with a really simple python code:

import timeit
definition="""\
class A(object):
    a = 1
a = A()
"""

stm="""\
hasattr(a, 'a')
"""
print timeit.timeit(stmt=stm, setup=definition, number=10000000)

stm="""\
getattr(a, 'a')
"""
print timeit.timeit(stmt=stm, setup=definition, number=10000000)

结果为:

$ python test.py
hasattr(a, 'a')
1.26515984535

getattr(a, 'a')
1.32518696785

我还尝试了如果该属性不存在并且getattr和hasattr之间的差异较大时会发生什么情况。因此,到目前为止,我所看到的是getattr比hasattr慢,但是在文档中说它叫做getattr。

I´ve tried also what happens if the attribute doesn´t exists and the differences between getattr and hasattr are bigger. So what I´ve seen so far is that getattr is slower than hasattr, but in the documentation it says that it calls getattr.

我已经搜索了CPython实现 hasattr getattr ,而且似乎都调用了下一个函数:

I´ve searched the CPython implementation of hasattr and getattr and it seems that both call the next function:

v = PyObject_GetAttr(v, name);

但是getattr中的样板文件比hasattr中的样板文件要慢得多。

but there is more boilerplate in getattr than in hasattr that probably makes it slower.

有人知道在文档中为什么我们说hasattr调用getattr吗?我们似乎鼓励用户在实际上不是由于性能而使用getattr代替hasattr吗?

Does anyone knows why in the documentation we say that hasattr calls getattr and we seem to encourage the users to use getattr instead of hasattr when it really isn´t due to performance? Is just because it is more pythonic?

也许我在测试中做错了:)

Maybe I am doing something wrong in my test :)

谢谢,

劳尔

推荐答案

文档不鼓励使用,该文档只是说显而易见的。 hasattr 是这样实现的,从属性获取器中抛出 AttributeError 可以使该属性看起来像存在。这是一个重要的细节,这就是在文档中明确说明的原因。例如考虑以下代码:

The documentation does not encourage, the documentation just states the obvious. The hasattr is implemented as such, and throwing an AttributeError from a property getter can make it look like the attribute does not exist. This is an important detail, and that is why it is explicitly stated in the documentation. Consider for example this code:

class Spam(object):
    sausages = False

    @property
    def eggs(self):
        if self.sausages:
            return 42
        raise AttributeError("No eggs without sausages")

    @property
    def invalid(self):
        return self.foobar


spam = Spam()
print(hasattr(Spam, 'eggs'))

print(hasattr(spam, 'eggs'))

spam.sausages = True
print(hasattr(spam, 'eggs'))

print(hasattr(spam, 'invalid'))

结果是

True
False
True
False

这是垃圾邮件类具有用于鸡蛋,但由于如果不是self.sausages ,则getter会引发 AttributeError ,因此该实例类不 有麻烦 鸡蛋

That is the Spam class has a property descriptor for eggs, but since the getter raises AttributeError if not self.sausages, then the instance of that class does not "hasattr" eggs.

Oth除此之外,仅在不需要该值时使用 hasattr ;如果需要该值,请使用带有两个参数的 getattr 并捕获异常或3个参数,第三个是明智的默认值。

Other than that, use hasattr only when you don't need the value; if you need the value, use getattr with 2 arguments and catch the exception, or 3 arguments, the third being a sensible default value.

使用 getattr()(2.7.9)的结果:

The results using getattr() (2.7.9):

>>> spam = Spam()
>>> print(getattr(Spam, 'eggs'))
<property object at 0x01E2A570>
>>> print(getattr(spam, 'eggs'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in eggs
AttributeError: No eggs without sausages
>>> spam.sausages = True
>>> print(getattr(spam, 'eggs'))
42
>>> print(getattr(spam, 'invalid'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 10, in invalid
AttributeError: 'Spam' object has no attribute 'invalid'
>>>

这篇关于Python hasattr与getattr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆