Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

unexpected behaviour playing with dynamic methods

11 views
Skip to first unread message

Marc Aymerich

unread,
Feb 23, 2012, 6:52:27 AM2/23/12
to
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?

Thanks !!!
marc

Peter Otten

unread,
Feb 23, 2012, 8:05:24 AM2/23/12
to pytho...@python.org
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))



Marc Aymerich

unread,
Feb 23, 2012, 8:44:46 AM2/23/12
to
hehe, yeah, after sending my email I realized that it was obvious, but
the true is I came up with this problem in a more complex situation
involving lot's of imports and so on.. so the question: wtf is going
on?? came up to me at this time :P

> 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))

Wow Peter, I was expecting one solution and you give me 3 amazing
solutions!! :) Thanks a lot!

btw I always wondered for what functools.partial can be useful, now I
know an example :)
0 new messages