我最近读了一些关于hasattr的tweets和python documentation,上面说:
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和getattr的CPython实现,似乎两者都调用了下一个函数:
v = PyObject_GetAttr(v, name);
但是getattr中的样板文件比hasattr中的要多,这可能会使它变慢。
有没有人知道为什么在文档中我们说hasattr调用getattr,并且我们似乎鼓励用户使用getattr而不是hasattr,而实际上这并不是由于性能的原因?只是因为它更像Python?
也许我在考试中做错了什么:)
谢谢
劳尔
似乎
hasattr
有吞咽异常的问题(至少in Python 2.7),所以在修复之前最好远离它。例如,the following code:
文件不鼓励,文件只是说明显而易见的。
hasattr
就是这样实现的,从属性getter抛出一个AttributeError
可以使它看起来像属性不存在。这是一个重要的细节,这就是为什么它会在文档中明确说明。例如,考虑以下代码:结果是
即
Spam
类有一个eggs
的属性描述符,但是由于getter引发了AttributeError
,如果not self.sausages
,则该类的实例不会“hasattr
”eggs
”。除此之外,仅当您不需要该值时才使用
hasattr
;如果您需要该值,请使用带2个参数的getattr
,并捕获异常或3个参数,第三个参数是合理的默认值。使用
getattr()
(2.7.9)的结果:相关问题 更多 >
编程相关推荐