Python 继承基于 __init__ 值的魔术方法

标签 python python-2.7

假设我有一个单个X . X的目的|是包裹一个listdict并提供事件监听功能。一切正常。

class X(object):
    def __init__(self, obj)
        self._obj = obj

    def __getattr__(self, name):
        # do stuff with self._obj

    def __getitem__(self, key):
        return self._obj[key]

    def __setitem__(self, key, val):
        self._obj[key] = val

    # rest of functionality ...

所以这可以用来包装 dict像这样:

x = X({
    'foo' : False
})

x.listen('foo', callback)

X['foo'] = True         # triggers event
X.update({
    'foo' : False       # triggers event
})

或者一个list :

x = X([1,2])

x.listen(callback)

X.append(1)        # triggers event
X[0] = 10          # triggers event

太棒了。几乎是我想要完成的...

现在的问题是,因为 X两者都是listdict对象,它不能从任何一个继承。这意味着我没有魔法类函数,例如 __contains__ .

导致这样的代码

d = X({
        'foo' : True    
    })

    if 'foo' in d:
        print 'yahoo!'

抛出 KeyError .

如果不在 X 中定义我需要的所有魔法方法,我该如何解决这个问题? .如果我这样做,对于这些定义中的每一个,我都必须根据是否 self._obj 编写两个返回值。是 listdict .

一开始我想我可以用元类来做这件事,但这似乎不是一个解决方案,因为我需要访问传递的值来检查它是否是 dictlist .

最佳答案

一种简单的方法是使用代理类,例如 wrapt.ObjectProxy .除了覆盖的方法外,它的行为与“代理”类完全一样。但是,您可以简单地使用 self.__wrapped__ 来访问“未代理”对象,而不是 self._obj

from wrapt import ObjectProxy

class Wrapper(ObjectProxy):
    def __getattr__(self, name):
        print('getattr')
        return getattr(self.__wrapped__, name)

    def __getitem__(self, key):
        print('getitem')
        return self.__wrapped__[key]

    def __setitem__(self, key, val):
        print('setitem')
        self.__wrapped__[key] = val

    def __repr__(self):
        return repr(self.__wrapped__)

如果你包装一个字典,这就像一个字典:

>>> d = Wrapper({'foo': 10})
>>> d['foo']
getitem
10
>>> 'foo' in d   # "inherits" __contains__
True

和列表一样,如果列表被包装:

>>> d = Wrapper([1,2,3])
>>> d[0]
getitem
1
>>> for i in d:   # "inherits" __iter__
...     print(i)
1
2
3

关于Python 继承基于 __init__ 值的魔术方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46367953/

相关文章:

python - 过滤 Pandas 系列中的特定单词(具有变体)

python - django runserver 的这个特定日志输出来自哪里

python - 在预先排序的 DataFrame 上使用 pandas groupby 的迭代顺序

python - 将变量分配给具有相同键的字典项

python - 如何处理有多个json对象的文件并在文件中添加新的json对象?

python - 如何重复连接numpy数组?

python - 如何在Python中对多个字典进行线性组合?

python - 尝试设置 virtualenv 在安装 vatic 时出现错误 'cannot import name _remove_dead_weakref'

Python-Numpy 矩阵乘法

python - 如何将部分函数绑定(bind)为 Python 类实例上的方法