- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我最近一直在阅读一些 tweets和 python 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
hasattr
”eggs
。
除此之外,仅当您不需要该值时才使用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/
Python版本 python -VPython 2.7.9::Anaconda 2.0.1 (x86_64) 如果没有返回或退出,则会出现错误: 第 16 行,正在播放 房间 = getattr(自
使用常规 python,我可以获得 getattr(object, att) 但在 Jinja2 中,我得到: jinja2.exceptions.UndefinedError jinja2.exce
有没有办法获取下面name的变量? def save_info(self): name = 'hello' var1 = 'other item' var2 = 1 .
从python官方文档中,我看到了getattr();的正常表达 getattr(对象,名称[,默认]) 我很明白。例如,我可以这样做: >>> def a(): ... pass ... >
根据我的理解,getattr(object, "method") 等同于 object.method()。如果这是真的,那么使用 getattr 有什么意义? 最佳答案 如果您将属性名称作为字符串,则
因此,在我的代码中使用 getattr 时,我发现了以下内容: myVariable = foo.A.bar 有效...但是像这样: B = "A" myVariable = getattr(foo,
我正在使用一个代码库,其中包含一行我真的无法理解: x, x, z = getattr(ReceiveFile, maxsizes)(input, args) 所以如果最后没有第二个元组,它就是 x,
我一直在深入了解 python 中的 getattr() 函数。从那本书中我知道它与模块一起工作得很好——毫无疑问!我进行了一些测试,但我不知道我将 getattr() 与特定变量一起使用的那段代码有
我有两个类(class)。一个类具有属性 x 但没有 y,另一个类具有属性 y 但没有 x。 我有一个函数接受任一类作为参数。是否有一种单行方法可以将新变量分配给 x 属性(如果存在)或 y 属性(如
我有这个代码; class NumberDescriptor(object): def __get__(self, instance, owner): name = (hasa
我要去 Calling a function of a module from a string with the function's name in Python但是每当我在我的程序中调用我的类时
我有一个简单的用例,我有一个类: class A: def meth1(self, name): ... def meth2(self, name, funcname): #
构造 getattr(obj, 'attr1.attr2', None) 不起作用。替换此结构的最佳做法是什么?将其分成两个 getattr 语句? 最佳答案 您可以使用 operator.attrg
我不知道这是否是 getattr built_in 方法的预期行为。getattr 也会执行默认的(第三个)参数,即使实际参数(第二个)满足条件。示例: def func(): print('
这个问题在这里已经有了答案: Why use setattr() and getattr() built-ins? (5 个答案) 关闭 7 年前。 这段代码有什么区别吗,它使用点符号来访问属性:
我正在尝试使用 Python 的 getattr() 从我无法控制的各种 API 获得的大量对象中提取数据。我的想法是遍历一个异类对象列表,并尝试对它们使用 getattr(),直到我提取出我需要的所
getatter()通过方法名字符串调用方法,这个方法最主要的作用就是实现反射机制,也就是说可以通过字符串获取方法实例,这样就可以把一个类可能要调用的方法放到配置文件里,需要的时候进行动态加载。
编辑:我可能会在这里落入 XY 问题陷阱。这就是我真正想要的 know . 我有以下功能: def foo(): bar = funcToGetBar() return bar.getattr
我正在用 Dojo 1.6 编写一个可以修改属性值的 dojo 函数: function replaceAttributeDojo(obj, attrName, newValue) {
我无法使函数 getattr 工作。这是我的代码: print ConfigConsModel()._meta.get_all_field_names() #['codesectrepmodel',
我是一名优秀的程序员,十分优秀!