让我们想象一下我有一个单独的类X.目的X是包装list或dict提供事件监听功能.一切顺利.
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 ...
Run Code Online (Sandbox Code Playgroud)
所以这可以用来包装dict如此:
x = X({
'foo' : False
})
x.listen('foo', callback)
X['foo'] = True # triggers event
X.update({
'foo' : False # triggers event
})
Run Code Online (Sandbox Code Playgroud)
或者list:
x = X([1,2])
x.listen(callback)
X.append(1) # triggers event
X[0] = 10 # triggers event
Run Code Online (Sandbox Code Playgroud)
大.几乎是我想要完成的......
现在目前的问题是,因为X是两个list和dict对象,它不能从任何继承.这意味着我没有魔术类的功能,比如__contains__.
这导致这样的代码
d = X({
'foo' : True
})
if 'foo' in d:
print 'yahoo!'
Run Code Online (Sandbox Code Playgroud)
投掷一个KeyError.
如何在不定义我需要的每一种神奇方法的情况下解决这个问题X.如果我这样做了,为每个定义的,我将不得不编写基于断是否两个返回值self._obj是一个list或dict.
我认为我最初可以用元类来做这个,但这似乎不是一个解决方案,因为我需要访问传递的值来检查它是否是a dict或list.
例如,一种简单的方法是使用代理类wrapt.ObjectProxy.除了重写的方法之外,它的行为与"代理"类完全相同.但是,self._obj您可以直接使用self.__wrapped__访问"未代理"的对象.
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__)
Run Code Online (Sandbox Code Playgroud)
如果你包装一个字典,这就像一个字典:
>>> d = Wrapper({'foo': 10})
>>> d['foo']
getitem
10
>>> 'foo' in d # "inherits" __contains__
True
Run Code Online (Sandbox Code Playgroud)
并且像列表一样,如果列表被包装:
>>> d = Wrapper([1,2,3])
>>> d[0]
getitem
1
>>> for i in d: # "inherits" __iter__
... print(i)
1
2
3
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
592 次 |
| 最近记录: |