unexpected behaviour playing with dynamic methods

Peter Otten __peter__ at web.de
Thu Feb 23 14:05:24 CET 2012

Marc Aymerich wrote:

> Hi,
> I'm playing a bit with python dynamic methods and I came up with a
> scenario that I don't understant. Considering the follow code:
> # Declare a dummy class
> class A(object):
>     pass
> # generate a dynamic method and insert it to A class
> for name in ['a', 'b', 'c']:
>     if name == 'b':
>         @property
>         def get_name(self):
>             return name
>         A.name = get_name
> a_instance = A()
> a_instance.name
> # So far I exptect that a_instance.name  returns 'b', since it has
> been created when name == 'b', but this is what actually returns:
>>>> a_instance.name
> 'c'
> just the last 'name' value.
> What can I do in order to generate a method like this but that returns
> 'b' ? What is wrong in my understanding of this pice of code?

Look at the method again:

>         def get_name(self):
>             return name

It returns the global variable name. Why would you expect to see a 
historical value of that variable?
If you want to capture the value of name at the time when get_name() is 
defined you have several options:

- The default argument trick:

def get_name(self, name=name):
    return name

- A closure:

def make_get_name(name):
    def get_name(self):
        return name
    return get_name
A.name = property(make_get_name(name))

- functools.partial()

def get_name(self, name):
    return name
A.name = property(partial(get_name, name=name))

More information about the Python-list mailing list