getattr() on nested functions?

Gabriel Rossetti gabriel.rossetti at arimaz.com
Wed Aug 20 11:03:10 EDT 2008


Bruno Desthuilliers wrote:
> Gabriel Rossetti a écrit :
>> Hello,
>>
>> I can't get getattr() to return nested functions,
>
> Of course. Nested functions are not attributes of their container 
> function.
Ok
>
>> I tried this :
>>
>>  >>> def toto():
>> ...     def titi():
>> ...             pass
>> ...     f = getattr(toto, "titi")
>> ...     print str(f)
>> ...
>>  >>> toto()
>> Traceback (most recent call last):
>>  File "<stdin>", line 1, in <module>
>>  File "<stdin>", line 4, in toto
>> AttributeError: 'function' object has no attribute 'titi'
>>  >>>
>>
>> I thought that since functions are objects, that I could obtain it's 
>> nested functions.
>
> Well, there's probably a very hackish way, but it's not worth the 
> pain. The fact that functions are objects doesn't make nested 
> functions methods of that object. If what you really want are methods, 
> then you can write your own callable:
>
> class _Test(object):
>   def request(self, params):
>       pass
>   def submit(self, params, values):
>       pass
>   def update(self, params, values):
>       pass
>   def delete(self, params):
>       pass
>   def __call__(self, action, *args):
>       return resultToXml(getattr(self, action)(*args))
>
> _test = _Test()
>
Yes, very hackish :-)
> But read the remaining before...
>
>> How come it doesn't work and what can I do to fix/replace it? I'm 
>> using it in code that is like this :
>>
>> def __test(self, action, *args):
>>        def request(params):
>>            pass
>>                  def submit(params, values):
>>            pass
>>                  def update(params, values):
>>            pass
>>                  def delete(params):
>>            pass
>>              result = getattr(__test, action)(*args)
>>              return resultToXml(result)
>>
>> where "action" is a string containing either "request", "submit", 
>> "update", or "delete". I was using an evel() with this form :
>>
>> result = eval(action + "(params, values)")
>
> Wrong use case for eval, as usual.
>
>> but I didn't find that very clean.
>
> indeed !-)
>
> locals() is your friend.
>
> def _test(self, action, *args):
>        def request(params):
>            pass
>        def submit(params, values):
>            pass
>        def update(params, values):
>            pass
>        def delete(params):
>            pass
>        result = locals()[action](*args)
>        return resultToXml(result)
>
>
Ok, thanks, that works :-), like I told Gabriel G., I keep on forgetting 
locals() exists :-)
> HTH
> -- 
> http://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list