[Baypiggies] Trivial OOP pattern problem

David Ginsburg dav9dg at gmail.com
Fri Jun 15 09:04:46 CEST 2012


Sorry for all the messages, but what I was doing was overkill.
After re-reading Brian's message I suppose you could just do this:

def __getattr__(self, name):
    def myf(*args, **kwargs):
      to_return = getattr(self.ctx, name)(*args, **kwargs)
      if to_return is None:
        to_return = self
      return to_return
    return myf

cheers,
David

On Fri, Jun 15, 2012 at 12:01 AM, David Ginsburg <dav9dg at gmail.com> wrote:

> Hmm, so I just tried to actually run this and for some
> reason inspect.getmembers(cairo.Context, predicate=inspect.ismethod)
> returns an empty list.
>
> Here's my ugly workaround:
>
> def make_chainable_context(cls):
>
>     def return_self_decorator(func):
>
>         def wrapper(self, *args, **kwargs):
>             to_return = func(self, *args, **kwargs)
>             if to_return is None:
>                 to_return = self
>             return to_return
>         return wrapper
>
>     #for method_name, method in inspect.getmembers(cairo.Context,
> predicate=inspect.ismethod):
>     for method_name, method in inspect.getmembers(cairo.Context):
>         if not method_name.startswith('__'):
>             setattr(cls, method_name, return_self_decorator(method))
>     return cls
>
> Pretty sure this accomplishes what you wanted :).
>
> cheers,
> David
>
> On Thu, Jun 14, 2012 at 11:56 PM, David Ginsburg <dav9dg at gmail.com> wrote:
>
>> Hello,
>> The problem with this is if a method needs to return a value other than
>> self, you break it.
>> This is probably hacky, but you could accomplish what you want doing the
>> following:
>>
>> import inspect
>> import functools
>>
>> def make_chainable_context(cls):
>>
>>     def return_self_decorator(func):
>>
>>         def wrapper(self, *args, **kwargs):
>>             to_return = func(self, *args, **kwargs)
>>             if to_return is None:
>>                 to_return = self
>>             return to_return
>>         return wrapper
>>
>>     for method_name, method in inspect.getmembers(cairo.Context,
>> predicate=inspect.ismethod):
>>         setattr(cls, method_name, return_self_decorator(method))
>>     return cls
>>
>>
>> @make_chainable_context
>> class ChainableContext(cairo.Context):
>>     pass
>>
>> This way methods that return something other than None are not broken.
>>
>> cheers,
>> David
>>
>> On Thu, Jun 14, 2012 at 11:28 PM, Brian Palmer <bpalmer at gmail.com> wrote:
>>
>>> On Thu, Jun 14, 2012 at 10:52 PM, Ian Zimmerman <itz at buug.org> wrote:
>>>
>>>>
>>>> Isaac> Hi, Why do you need each of the methods to return the instance?
>>>> Isaac> Can you just wrap the method calls in a function and return the
>>>> Isaac> instance?
>>>>
>>>> I am not married to the idea of a wrapper class, but I don't understand
>>>> what you propose instead.  What would the example code look like under
>>>> your scheme?
>>>>
>>>
>>> Your initial solution seems like it'd work:
>>> class Wrap(object):
>>>   def __init__(self, ctx):
>>>     self.ctx = ctx
>>>
>>>   def __getattr__(self, name):
>>>     def myf(*args, **kwargs):
>>>       getattr(self.ctx, name)(*args, **kwargs)
>>>       return self
>>>     return myf
>>>
>>> There are benefits to being less dynamic, but this might be good enough.
>>>
>>> _______________________________________________
>>> Baypiggies mailing list
>>> Baypiggies at python.org
>>> To change your subscription options or unsubscribe:
>>> http://mail.python.org/mailman/listinfo/baypiggies
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/baypiggies/attachments/20120615/6a0b0d83/attachment-0001.html>


More information about the Baypiggies mailing list