Is There A Way To Access The Formal Parameters If You Implement __getattribute__
Solution 1:
__getattribute__ simply returns the attribute that was requested, in case of a method, the __call__ interface is then used to call it.
Instead of returning the method, return a wrapper around it, for instance:
def__getattribute__(self, attr):
defmake_interceptor(callble):
deffunc(*args, **kwargs):
print args, kwargs
return callble(*args, **kwargs)
return func
att = self.__dict__[attr]
ifcallable(att):
return make_interceptor(att)
Solution 2:
Method invocation in Python is two step process, first a function is looked up, then it is invoked. For a more involved discussion see my answer to this question.
So you would need to do something like this:
def__getattribute__(self, key):
if key == "something_interesting":
deffunc(*args, **kwargs):
# use arguments, and possibly the self variable from outer scopereturn func
else:
returnobject.__getattribute__(self, key)
Also, overriding __getattribute__ is usually a bad idea. Because it is called on all attribute accesses it is really easy to end up in an infinite loop, and even if you do everything correctly it ends up being a pretty big performance hit. Are you sure that __getattr__ won't be enough for your purposes? Or maybe even a descriptor object that returns functions. Descriptors are usually a lot better at reuse.
Solution 3:
Honestly I'm not sure I understand your question. If you want a way to override getattribute and yet keep the original attributes you can use __dict__
def__getattribute__(self, attr):
if attr inself.__dict__:returnself.__dict__[attr]
# Add your changes here
Solution 4:
I don't think you can. __getattribute__
doesn't intercept the method call, it only intercepts the method name lookup. So it should return a function (or callable object), which will then be called with whatever parameters specified at the call site.
In particular, if it returns a function which takes (*args, **kwargs)
, then in that function you can examine the arguments however you want.
I think. I'm not a Python expert.
Solution 5:
Here is a variation on Unknown's suggestion that returns a callable "wrapper" instance in place of the requested function. This does not require decorating any methods:
classF(object):
def__init__(self, func):
self.func = func
returndef__call__(self, *args, **kw):
print"Calling %r:" % self.func
print" args: %r" % (args,)
print" kw: %r" % kw
return self.func(*args,**kw)
classC(object):
def__init__(self):
self.a = 'an attribute that is not callable.'returndef__getattribute__(self,name):
attr = object.__getattribute__(self,name)
ifcallable(attr):
# Return a callable object that can examine, and even# modify the arguments prior to calling the method.return F(attr)
# Return the reference to any non-callable attribute.return attr
defm(self, *a, **kw):
print"hello from m!"return>>> c=C()
>>> c.a
'an attribute that is not callable.'>>> c.m
<__main__.F object at 0x63ff30>
>>> c.m(1,2,y=25,z=26)
Calling <bound method C.m of <__main__.C object at 0x63fe90>>:
args: (1, 2)
kw: {'y': 25, 'z': 26}
hello from m!
>>>
Ants Aasma above makes an important point regarding recursion when using __getattribute__
. It is called by all attribute lookups on self
, even those inside of the __getattribute__
method. Several of the other examples include references to self.__dict__
inside of __getattribute__
which will result in recursing until you exceed the maximum stack depth! To avoid this, use one of the
base class' versions of __getattribute__
(e.g. object.__getattribute__(self,name)
.)
Post a Comment for "Is There A Way To Access The Formal Parameters If You Implement __getattribute__"