gpt4 book ai didi

python - __getattr__ 不适用于 __enter__ -> AttributeError

转载 作者:太空狗 更新时间:2023-10-30 01:24:15 24 4
gpt4 key购买 nike

我想在使用 __getattr__ 重定向调用的对象上使用 with
但是,这似乎不适用于 __enter__

方法

请考虑以下简化代码来重现错误:

class EnterTest(object):
def myenter(self):
pass
def __exit__(self, type, value, traceback):
pass

def __getattr__(self, name):
if name == '__enter__':
return self.myenter

enter_obj = EnterTest()
print getattr(enter_obj, '__enter__')

with enter_obj:
pass

输出:

<bound method EnterTest.myenter of <__main__.EnterTest object at 0x00000000021432E8>>
Traceback (most recent call last):
File "test.py", line 14, in <module>
with enter_obj:
AttributeError: __enter__

为什么它不返回到 __getattr__ 因为对象上不存在 __enter__

当然,如果我只是创建一个 __enter__ 方法并从那里重定向,我就可以让它工作,但我想知道为什么它不工作。

我的 python 版本如下:

C:\Python27\python27.exe 2.7 (r27:82525, Jul  4 2010, 07:43:08) [MSC v.1500 64 bit (AMD64)]

最佳答案

根据上游,此工作是 2.6 中的错误,已在 2.7 中“修复”。简短的回答是像 __enter__ 这样的方法。在类上查找,而不是在对象上查找。

此模糊行为的文档位于 http://docs.python.org/reference/datamodel#specialnames : x[i] is roughly equivalent to ... type(x).__getitem__(x, i) for new-style classes .

您可以通过其他特殊方法看到此行为:

class foo(object):
def __iadd__(self, i):
print i
a = foo()
a += 1

class foo2(object):
def __getattr__(self, key):
print key
raise AttributeError
b = foo2()
b += 1

class foo3(object):
pass
def func(self, i):
print i
c = foo3()
c.__iadd__ = func
c += 1

第一部作品;后两个没有。 Python 2.6 不符合 __enter__ 的这种行为和 __exit__ ,但 2.7 会。 http://bugs.python.org/issue9259

也就是说,这些方法不能像任何其他属性那样动态处理,这是令人痛苦的不一致。同样,您不能使用 __getattribute__ 检测对这些方法的访问。就像您可以使用任何其他方法一样。我找不到任何内在的设计逻辑。 Python 通常非常一致,这是一个相当令人不快的缺点。

关于python - __getattr__ 不适用于 __enter__ -> AttributeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4146095/

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