pythonpython-2.7dynamic-attributes

Python dynamic attribute value bind to method


after reading several posts here I am still a bit confused on the correct way to implement a Class dynamic attribute with a function as value.

Been some time since I touched python and now I am a bit stuck.

I have the following class:

class RunkeeperUser(object):

    def __init__(self, master):
        self.master = master
        # Get the user methods and set the attributes
        for user_method, call in self.master.query('user').iteritems():
            # Should not get the value but bind a method
            setattr(
                self,
                user_method,
                self.master.query(call)
            )

    def get_user_id(self):
        return self.user_id


    def query(self, call):
        return self.master(call)

Right now as you can see when setting the attribute it directly executes the self.master.query(call) and already results are there when the attribute is accessed.

The question is how can I make this attribute value dynamic upon runtime and not already executed?

I have tried:

setattr(
                self,
                user_method,
                lambda: self.master.query(call)
            )

But that does not work well for some reason. Any help/guidance or best principals to achieve the described result?


Solution

  • This is a well known gotcha. You have to bind your argument's current value in the lambda, ie:

    setattr(
            self,
            user_method,
            lambda call=call: self.master.query(call)
            )