如何在Python中覆盖__getattribute __()

时间:2011-09-17 15:06:43

标签: python

我正在尝试修改实例的__getattribute__()方法,正如您可能已经知道的那样,__getattirbute__是Python中的只读属性(编辑:对于某些对象,可能是编辑:对于其他对象)它不是)。我想到的是,创建一个像这样的新对象:

def create_new_instace(old_instance):
    class temp(old_instance.__class__):
        def __init__(self,*args,**kwargs):
            "Since we will copy an already inited instance"
            pass
        def __getattribute__(self,attr):
           # do stuff
    new_instance = temp()
    # magically copy all attrs of old_instance to new_instance
    return new_instance

这种事情有可能吗?我没有特别的问题,我只是想知道如何做到这一点。

3 个答案:

答案 0 :(得分:2)

实际上,是的。检查__getattribute____getattr__方法here

之间的差异

您可以为实例的字段__getattribute__分配新值,除非__setattr__明确禁止该字段。在你的python提示符中试试这个:

>>>class A(object):
>>>    pass
>>>A().__getattribute__ = myFunc
>>>A().__getattr__ = myFunc

如果__setattr__不允许您这样做,则必须执行类似您提议的解决方案。检查模块copy是否有“神奇复制”属性。

答案 1 :(得分:0)

Python 2.2+可能就像您尝试它一样,在这里阅读(搜索 getattirbute )以了解您应该考虑的具体事项: http://www.python.org/download/releases/2.2/descrintro/

答案 2 :(得分:0)

我不确定我理解你的目标。如果您只是想创建一个与另一个对象重复的新对象,则可以使用

from copy import copy
new_instance = copy( old_instance )

这会创建一个浅表副本。对于对象的深层副本,还有copy.deepcopy

如果您想要一个派生类,该派生类具有另一个实例属性的副本(可能是您需要动态制作的其他自定义项),您可以使用:

from copy import copy
def create_new_instance( old_instance ):
    class NewClass( old_instance.__class__ ):
        """
        dynamic custom class
        """
        # ... customizations

    new_instance = copy( old_instance )
    new_instance.__class__ = NewClass

这对某些系统类类型不起作用,__class__不可分配。 (例如list,tuple,str,我想)。

在这些情况下,您可以使用__new__来定义派生类...但我不确定是否存在定义参数的“标准”方法 - 您可能会缩减为经历案例。

请注意,除非您有其他动态创建新类的原因,否则无需在函数内定义它。