我发现我能够覆盖内置类__iadd__
之类的方法,但仅仅通过重新分配__iadd__
我无法改变他们的行为:
class OverrideList(list):
def __iadd__(self, x):
print("You'll see this")
return list.__iadd__(self, x)
class ReassignList(list):
def iadd(self, x):
print("You'll never see this")
return list.__iadd__(self, x)
def __init__(self, *args, **kw):
list.__init__(self, *args, **kw)
self.__iadd__ = self.iadd
ol = OverrideList()
ol += range(3)
rl = ReassignList()
rl += range(3)
我能做些什么让我接受ReassignList.iadd?
我最初认为关于 iadd 的有趣之处在于它是"插槽包装"而不是方法,但这个片段让我持怀疑态度:
class OverrideThenReassign(OverrideList):
def iadd(self, x):
print("You won't see this either")
return list.__iadd__(self, x)
def __init__(self, *args, **kw):
list.__init__(self, *args, **kw)
print("OverrideThenReassign.__iadd__ starts out as {} not as a slot wrapper".format(self.__iadd__.__class__))
self.__iadd__ = self.iadd
通过使用代码包装方法将问题中的数据结构保存到磁盘,动机是概括了writing a PersistentList
subclass of list
的技术。有here草稿。
编辑:此问题与this one大致相同。这个问题被埋没在numpy gobbledygook中,所以我不会将此标记为副本,除非SO超级明星建议这样做。
答案 0 :(得分:0)
我使用ProxyTypes为您提供了解决方案(*使我们无法实施Proxy Pattern
#!/usr/bin/env python
from __future__ import print_function
from peak.util.proxies import ObjectWrapper
class ListProxy(ObjectWrapper):
def __init__(self, obj):
super(ListProxy, self).__init__(obj)
def __iadd__(self, other):
print("You'll see this.")
return super(ListProxy, self).__iadd__(other)
xs = ListProxy([1, 2, 3])
xs += [4, 5, 6]
<强>输出:强>
$ python -i foo.py
You'll see this.
>>> xs
[1, 2, 3, 4, 5, 6]
>>>
答案 1 :(得分:0)
无需另外下载即可满足您的需求:
class perpList( list ):
def __init__(self, *args, **kwargs):
super(perpList, self).__init__(*args, **kwargs)
def __iadd__(self,x):
print "adding element {0}".format( x)
return super(perpList, self).__iadd__(x)
a = perpList([1,2,3,4,5,6])
print a
a += [19]
print a
输出:
[1, 2, 3, 4, 5, 6]
adding element [19]
[1, 2, 3, 4, 5, 6, 19]
在repl.it上测试代码 - Python 2.7.2。
詹姆斯&#39;解决方案的好处是,您基本上可以只使用一个类来代理任何内容,但具有附加的依赖性,并且(在我看来,可读性的数量会有很小的减少 - 因为通过检查您实际上代理的内容并不明显。)
答案 2 :(得分:0)
以下是基于@ user2357112评论的答案(&#34;在课程级别包装方法,而不是单个实例。&#34;)
class ReassignList(list):
@staticmethod
def iadd(left, right):
print("Now this works!")
return list.__iadd__(left, right)
def __init__(self, *args, **kw):
list.__init__(self, *args, **kw)
ReassignList.__iadd__ = ReassignList.iadd