gpt4 book ai didi

Python hasattr 与 getattr

转载 作者:太空狗 更新时间:2023-10-29 17:59:27 25 4
gpt4 key购买 nike

我最近一直在阅读一些 tweetspython documentation关于 hasattr,它说:

hasattr(object, name)

The arguments are an object and a string. The result is True if the string is the name of >> one of the object’s attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an AttributeError or not.)

Python 中有一句格言,请求宽恕比请求许可更容易,我通常同意这一点。

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

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。

我搜索了 hasattr 的 CPython 实现和 getattr并且似乎都调用了下一个函数:

v = PyObject_GetAttr(v, name);

但是 getattr 中的样板文件比 hasattr 中的多,这可能会使它变慢。

有谁知道为什么在文档中我们说 hasattr 调用 getattr 并且我们似乎鼓励用户使用 getattr 而不是 hasattr 而实际上不是因为性能?仅仅是因为它更 pythonic 吗?

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

谢谢,

劳尔

最佳答案

文档不鼓励,文档只是陈述显而易见的事情。 hasattr 是这样实现的,从属性 getter 中抛出 AttributeError 可以让它看起来像属性不存在。这是一个重要的细节,这就是文档中明确说明的原因。例如考虑这段代码:

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

那是 Spam 类有一个 eggs 的属性描述符,但是如果 not self.sausages getter 会引发 AttributeError ,则该类的实例不“hasattreggs

除此之外,仅当您不需要该值时才使用hasattr;如果您需要该值,请使用带有 2 个参数的 getattr 并捕获异常,或者使用 3 个参数,第三个参数是合理的默认值。

使用 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,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24971061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com