0

I have problem sharing members of a class with its dynamically generated methods.

For example below x accessed from __init__ and from normal_test is different fro x accessed from dynamically bounded methods test and setx:

class Foo:
    def __init__(self):
        self.x = 10
    def normal_test(self):
        print self.x

def bar(self):
    print self.x
def setx_method(self,x):
    self.x = x

setattr(Foo, "test", classmethod(bar))
setattr(Foo, "setx", classmethod(setx_method))

f = Foo();
f.setx(5)
f.test()
f.normal_test()

How should I write the code such that self.x would refer to same x?

Remi Guan
  • 21,506
  • 17
  • 64
  • 87
Artyom
  • 31,019
  • 21
  • 127
  • 215

2 Answers2

1

Analyzing

setattr(Foo, "setx", classmethod(setx_method))

It's equivalent to

@classmethod
def setx_method(self,x):
    self.x=x

Now when you invoke f.setx(5), it actually binds f's class(ie, Foo) with self and 5 with x and thus it executed Foo.x = 5

In short you have two x in Foo, one is instance member x and one is class member x.

f.setx(5)        # sets class x
f.test()         # print class variable x
f.normal_test()  # print instance variable x
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
Mangu Singh Rajpurohit
  • 10,806
  • 4
  • 68
  • 97
  • Thanks I failed to understand that setting an attribute method on class actually defined a method.. no need of class method. – Artyom Nov 09 '15 at 11:06
0

You shouldn't use @classmethod with self, because it points to your class instance, while in @classmethod you should use cls as it points to whole your class.

See here: Meaning of @classmethod and @staticmethod for beginner?


So the simplest solution is just remove classmethod:

setattr(Foo, "test", bar)
setattr(Foo, "setx", setx_method)
Community
  • 1
  • 1
Nhor
  • 3,860
  • 6
  • 28
  • 41