gpt4 book ai didi

python-3.x - 所有 Python dunder 方法的列表 - 您需要实现哪些方法才能正确代理对象?

转载 作者:行者123 更新时间:2023-12-04 11:19:49 25 4
gpt4 key购买 nike

我正在尝试创建一个对象代理。
属性/属性查找可以通过简单地实现 __getattribute__ 来完成。 , __setattr____delattr__方法。
但是,其他功能如 len(x), x[], bool(x)需要其他 Dunder 方法,例如 __len__, __getitem__, __bool__将要执行。如果您没有在代理类上实现这些,但是您代理的对象支持它们,您的代理将不完整并导致运行时错误。

因此,我想拥有一份我需要实现的所有事情的综合 list ,但我在网上找不到任何可靠的 list 。

这是我从 typing 中获得的 97 个独特的 dunder 方法名称和 builtins模块。
我知道他们中的很多人在做什么,但有些人我不知道。为我的代理类实现所有或大部分它们会很痛苦,所以如果有解决方法我会很高兴。

__abs__
__add__
__aenter__
__aexit__
__aiter__
__and__
__anext__
__await__
__bool__
__bytes__
__call__
__class__
__cmp__
__complex__
__contains__
__delattr__
__delete__
__delitem__
__delslice__
__dir__
__div__
__divmod__
__enter__
__eq__
__exit__
__float__
__floordiv__
__format__
__fspath__
__ge__
__get__
__getattribute__
__getitem__
__getnewargs__
__getslice__
__gt__
__hash__
__iadd__
__iand__
__import__
__imul__
__index__
__init__
__init_subclass__
__instancecheck__
__int__
__invert__
__ior__
__isub__
__iter__
__ixor__
__le__
__len__
__lshift__
__lt__
__mod__
__mul__
__ne__
__neg__
__new__
__next__
__nonzero__
__or__
__pos__
__pow__
__prepare__
__radd__
__rand__
__rdiv__
__rdivmod__
__reduce__
__reduce_ex__
__repr__
__reversed__
__rfloordiv__
__rlshift__
__rmod__
__rmul__
__ror__
__round__
__rpow__
__rrshift__
__rshift__
__rsub__
__rtruediv__
__rxor__
__set__
__setattr__
__setitem__
__setslice__
__sizeof__
__str__
__sub__
__subclasscheck__
__subclasses__
__truediv__
__xor__

最佳答案

要代理一个对象,您只需要实现该对象具有的 dunder 方法,因此在最简单的世界中,您不需要做任何特殊的事情来代理它们,而您还没有这样做来代理对象的其他属性。
然而,问题在于 dunder 方法是在类上查找的,而不是在对象上查找,所以例如 Foo().bar会查bar如果实例没有 bar,则在回退到类之前在实例上属性,Foo() + 5会查__add__上类Foo ,完全忽略实例。也就是说,如果实例确实具有名为 __add__ 的实例属性,然后 Foo() + 5仍然不会使用该实例属性。
因此,要代理那些 dunder 方法,它们需要在类级别而不是实例级别进行代理。

from functools import wraps

def proxy_function(name, f):
@wraps(f)
def proxied_f(*args, **kwargs):
print('Proxying function:', name)
return f(*args, **kwargs)
return proxied_f

def proxy_object(obj):
class Proxy:
def __getattr__(self, name):
print('Proxying getattr:', name)
return getattr(obj, name)
def __hasattr__(self, name):
print('Proxying hasattr:', name)
return hasattr(obj, name)
def __setattr__(self, name, value):
print('Proxying setattr:', name, '=', repr(value))
setattr(obj, name, value)
def __delattr__(self, name):
print('Proxying delattr:', name)
delattr(obj, name)

for name, f in obj.__class__.__dict__.items():
# don't try to overwrite __class__, __getattr__, etc.
if callable(f) and name not in Proxy.__dict__:
f = proxy_function(name, f)
setattr(Proxy, name, f)

return Proxy()
用法:
>>> class Foo:
... def __add__(self, other):
... return 'Adding with ' + repr(other)
...
>>> foo = Foo()
>>> proxy_foo = proxy_object(foo)
>>> foo + 5
'Adding with 5'
>>> proxy_foo + 5
Proxying function: __add__
'Adding with 5'

关于python-3.x - 所有 Python dunder 方法的列表 - 您需要实现哪些方法才能正确代理对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56238263/

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