unexpected behaviour playing with dynamic methods

M

Marc Aymerich

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:
'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
 
P

Peter Otten

Marc said:
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:
'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))
 
M

Marc Aymerich

Marc said:
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:

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?

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top