动态更改__iadd__和其他运算符的行为

时间:2014-07-14 03:28:12

标签: python dynamic persistence

我发现我能够覆盖内置类__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超级明星建议这样做。

3 个答案:

答案 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