让 spam
是某个类 Spam
的实例,并假设 spam.ham
是某个内置类型的对象,说 dict
。尽管 Spam
不是 dict
的子类,但我希望它的实例具有与常规 dict
相同的 API(即相同的方法具有相同的签名),但我想避免输入以下形式的无数样板方法:
def apimethod(self, this, that):
return self.ham.apimethod(this, that)
我尝试了以下方法:
class Spam(object):
def __init__(self):
self.ham = dict()
def __getattr__(self, attr):
return getattr(self.ham, attr)
...但它适用于“常规”方法,如 keys
和 items
,但不适用于 特殊方法,如 __setitem__
、__getitem__
和 __len__
:
>>> spam = Spam()
>>> spam.keys()
[]
>>> spam['eggs'] = 42
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Spam' object does not support item assignment
>>> spam.ham['eggs'] = 42
>>> foo.items()
[('eggs', 42)]
>>> spam['eggs']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Spam' object is not subscritable
>>> len(spam)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Spam' object has no len()
我尝试过的所有特殊方法都产生了类似的错误。
How can I automate the definition of special methods (so that they get referred to the delegate)?
澄清:我不一定要寻找利用标准方法查找序列的解决方案。我的目标是尽量减少样板代码。
谢谢!
最佳答案
如果您还需要一个禁止元类的解决方案,这可能没有帮助,但这是我想出的解决方案:
def _wrapper(func):
def _wrapped(self, *args, **kwargs):
return getattr(self.ham, func)(*args, **kwargs)
return _wrapped
class DictMeta(type):
def __new__(cls, name, bases, dct):
default_attrs = dir(object)
for attr in dir(dict):
if attr not in default_attrs:
dct[attr] = _wrapper(attr)
return type.__new__(cls, name, bases, dct)
class Spam(object):
__metaclass__ = DictMeta
def __init__(self):
self.ham = dict()
似乎可以满足您的需求:
>>> spam = Spam()
>>> spam['eggs'] = 42
>>> spam.items()
[('eggs', 42)]
>>> len(spam)
1
>>> spam.ham
{'eggs': 42}
如果在 Python 3.x 上使用 class Spam(object, metaclass=DictMeta)
并从 Spam
的正文中删除 __metaclass__
行.
关于python - 如何在 Python 中自动化 __special_methods__ 的委托(delegate)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8541137/