Re: How to mix-in __getattr__ after the fact?
On Tue, 08 Nov 2011 15:17:14 +1100, Lie Ryan wrote: > On 10/31/2011 11:01 PM, dhyams wrote: >> >> Thanks for all of the responses; everyone was exactly correct, and >> obeying the binding rules for special methods did work in the example >> above. Unfortunately, I only have read-only access to the class itself >> (it was a VTK class wrapped with SWIG), so I had to find another way to >> accomplish what I was after. >> >> > As a big huge hack, you can always write a wrapper class: > > class Wrapper(object): > def __init__(self, *args, **kwargs): > self.__object = MySWIGClass(*args, **kwargs) > def __getattr__(self, attr): > try: > return getattr(self.__object, attr) > except AttributeError: > ... That's not a hack, that's a well-respected design pattern called Delegation. http://rosettacode.org/wiki/Delegate http://en.wikipedia.org/wiki/Delegation_pattern In this case, you've implemented about half of automatic delegation: http://code.activestate.com/recipes/52295 which used to be much more important in Python prior to the type/class unification in version 2.2. To also delegate special dunder methods using new-style classes, see this: http://code.activestate.com/recipes/252151 -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: How to mix-in __getattr__ after the fact?
On 10/31/2011 11:01 PM, dhyams wrote: Thanks for all of the responses; everyone was exactly correct, and obeying the binding rules for special methods did work in the example above. Unfortunately, I only have read-only access to the class itself (it was a VTK class wrapped with SWIG), so I had to find another way to accomplish what I was after. As a big huge hack, you can always write a wrapper class: class Wrapper(object): def __init__(self, *args, **kwargs): self.__object = MySWIGClass(*args, **kwargs) def __getattr__(self, attr): try: return getattr(self.__object, attr) except AttributeError: ... -- http://mail.python.org/mailman/listinfo/python-list
Re: How to mix-in __getattr__ after the fact?
On Oct 31, 8:01 am, dhyams wrote: > Thanks for all of the responses; everyone was exactly correct, and > obeying the binding rules for special methods did work in the example > above. Unfortunately, I only have read-only access to the class > itself (it was a VTK class wrapped with SWIG), so I had to find > another way to accomplish what I was after. > Please share what you found as the other way. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to mix-in __getattr__ after the fact?
Thanks for all of the responses; everyone was exactly correct, and obeying the binding rules for special methods did work in the example above. Unfortunately, I only have read-only access to the class itself (it was a VTK class wrapped with SWIG), so I had to find another way to accomplish what I was after. On Oct 28, 10:26 pm, Lie Ryan wrote: > On 10/29/2011 05:20 AM, Ethan Furman wrote: > > > > > > > > > > > > > Python only looks up __xxx__ methods in new-style classes on the class > > itself, not on the instances. > > > So this works: > > > 8< > > class Cow(object): > > pass > > > def attrgetter(self, a): > > print "CAUGHT: Attempting to get attribute", a > > > bessie = Cow() > > > Cow.__getattr__ = attrgetter > > > print bessie.milk > > 8< > > a minor modification might be useful: > > bessie = Cow() > bessie.__class__.__getattr__ = attrgetter -- http://mail.python.org/mailman/listinfo/python-list
Re: How to mix-in __getattr__ after the fact?
On 10/29/2011 05:20 AM, Ethan Furman wrote: Python only looks up __xxx__ methods in new-style classes on the class itself, not on the instances. So this works: 8< class Cow(object): pass def attrgetter(self, a): print "CAUGHT: Attempting to get attribute", a bessie = Cow() Cow.__getattr__ = attrgetter print bessie.milk 8< a minor modification might be useful: bessie = Cow() bessie.__class__.__getattr__ = attrgetter -- http://mail.python.org/mailman/listinfo/python-list
Re: How to mix-in __getattr__ after the fact?
dhyams wrote: Python 2.7.2 I'm having trouble in a situation where I need to mix-in the functionality of __getattr__ after the object has already been created. Here is a small sample script of the situation: =snip import types class Cow(object): pass # this __getattr__ works as advertised. #def __getattr__(self,a): # print "CAUGHT INCLASS: Attempting to get attribute ",a def attrgetter(self,a): print "CAUGHT: Attempting to get attribute ",a bessie = Cow() bessie.__getattr__ = types.MethodType(attrgetter,bessie,Cow) # here, I should see my printout "attempting to get attribute" # but I get an AttributeException print bessie.milk ==snip If I call __getattr__ directly, as in bessie.__getattr__('foo'), it works as it should obviously; so the method is bound and ready to be called. But Python does not seem to want to call __getattr__ appropriately if I mix it in after the object is already created. Is there a workaround, or am I doing something wrongly? Thanks, Python only looks up __xxx__ methods in new-style classes on the class itself, not on the instances. So this works: 8< class Cow(object): pass def attrgetter(self, a): print "CAUGHT: Attempting to get attribute", a bessie = Cow() Cow.__getattr__ = attrgetter print bessie.milk 8< ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: How to mix-in __getattr__ after the fact?
On Fri, Oct 28, 2011 at 1:34 PM, dhyams wrote: > If I call __getattr__ directly, as in bessie.__getattr__('foo'), it > works as it should obviously; so the method is bound and ready to be > called. But Python does not seem to want to call __getattr__ > appropriately if I mix it in after the object is already created. Is > there a workaround, or am I doing something wrongly? Python looks up special methods on the class, not the instance (see http://docs.python.org/reference/datamodel.html#special-method-lookup-for-new-style-classes). It seems like you ought to be able to delegate the special attribute access from the class to the instance somehow, but I couldn't figure out how to do it in a few minutes of fiddling at the interpreter. -- Jerry -- http://mail.python.org/mailman/listinfo/python-list
How to mix-in __getattr__ after the fact?
Python 2.7.2 I'm having trouble in a situation where I need to mix-in the functionality of __getattr__ after the object has already been created. Here is a small sample script of the situation: =snip import types class Cow(object): pass # this __getattr__ works as advertised. #def __getattr__(self,a): # print "CAUGHT INCLASS: Attempting to get attribute ",a def attrgetter(self,a): print "CAUGHT: Attempting to get attribute ",a bessie = Cow() bessie.__getattr__ = types.MethodType(attrgetter,bessie,Cow) # here, I should see my printout "attempting to get attribute" # but I get an AttributeException print bessie.milk ==snip If I call __getattr__ directly, as in bessie.__getattr__('foo'), it works as it should obviously; so the method is bound and ready to be called. But Python does not seem to want to call __getattr__ appropriately if I mix it in after the object is already created. Is there a workaround, or am I doing something wrongly? Thanks, -- http://mail.python.org/mailman/listinfo/python-list