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.
精彩评论