开发者

How to overwrite __getattribute__() in Python

I am trying to modify __getattribut开发者_StackOverflow社区e__() 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). 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

You can assign new value to the instance's field __getattribute__ except if __setattr__ explicitly prohibits that. Try this in your python prompt:

>>>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. Check module copy for 'magically copying' attributes.


It is possible for Python 2.2+, just the way you attempt it, read here (search for getattirbute) for the specific things you should take into consideration: 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.

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. (e.g. list, tuple, str, I think).

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.

Note that unless you have other reasons for creating the new class dynamically, you needn't define it inside your function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜