python - 如何在 Python 中自动化 __special_methods__ 的委托(delegate)?

标签 python

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)

...但它适用于“常规”方法,如 keysitems,但不适用于 特殊方法,如 __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/

相关文章:

python - 如何处理 Tkinter 中的窗口关闭事件?

python - Azure 函数 blob 存储文件名

python - 我应该在这里使用哪种数据结构?

python - Celery:如何忽略和弦或链中的任务结果?

python - 查找单个地理数据框中所有多边形中包含的重叠区域

python - 无法弄清楚如何调试这个: ValueError: invalid literal for int() with base 10: '

python - tensorflow 中二维数组最小值到最大值的排序

python - 在目录和子目录中查找扩展名的文件?

python - 二维列表不起作用

python - 将 Flask 项目部署到 Heroku 时出现 "Install dependencies with pip"异常