简体   繁体   English

如何在Python中覆盖__getattribute __()

[英]How to overwrite __getattribute__() in Python

I am trying to modify __getattribute__() method for an instance, as you may already know, __getattirbute__ is read-only attribute in Python (edit: appereantly, for some objects it is, and for others it isn't). 我正在尝试修改实例的__getattribute__()方法,正如您可能已经知道的那样, __getattirbute__ getattirbute__是Python中的只读属性(编辑:显然,对于某些对象,对于其他对象,它不是)。 What I have in mind is, create a new object like this: 我的想法是,创建一个这样的新对象:

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

Is this kind of thing possible? 这种事可能吗? I am not having a particular problem, I just want to know how to do this. 我没有特别的问题,我只是想知道如何做到这一点。

Actually, yes. 其实,是。 Check difference between __getattribute__ and __getattr__ method here 这里检查__getattribute____getattr__方法之间的区别

You can assign new value to the instance's field __getattribute__ except if __setattr__ explicitly prohibits that. 您可以为实例的字段__getattribute__分配新值,除非__setattr__明确禁止它。 Try this in your python prompt: 在你的python提示符中试试这个:

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

If the __setattr__ won't allow you to do so, you have to do something like solution you proposed. 如果__setattr__不允许你这样做,你必须做一些像你提出的解决方案。 Check module copy for 'magically copying' attributes. 检查模块copy是否有“神奇复制”属性。

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

I am not sure I understand your goal. 我不确定我理解你的目标。 If you simply want to create a new object that is a duplicate of another object, you can use 如果您只是想创建一个与另一个对象重复的新对象,则可以使用

from copy import copy
new_instance = copy( old_instance )

This creates a shallow copy. 这会创建一个浅表副本。 There is also copy.deepcopy for deep copies of objects. 对于对象的深层副本,还有copy.deepcopy

If you want a derived class that has a copy of another instances attributes (an possibly other customizations, that you need to make dynamically for some reason), you can use: 如果您希望派生类具有另一个实例属性的副本(可能是其他自定义,您需要由于某种原因动态制作),您可以使用:

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

This won't work for some system class types, for which __class__ isn't assignable. 这对于某些系统类类型不起作用,因为__class__不可分配。 (eg list, tuple, str, I think). (例如list,tuple,str,我认为)。

In these cases you can define your derived class with __new__ ... but I'm not sure if there is a "standard" way to define the arguments -- you might be reduced to going through cases. 在这些情况下,您可以使用__new__来定义派生类...但我不确定是否有一种“标准”方式来定义参数 - 您可能会被简化为通过案例。

Note that unless you have other reasons for creating the new class dynamically, you needn't define it inside your function. 请注意,除非您有其他动态创建新类的原因,否则无需在函数内定义它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM