Reputation: 1985
I'm doing my first steps in Python 2.7 Metaprogramming, and wrote following code :
class MetaClass(type):
def __init__(cls, name, bases, attrs):
print "Defining class : %s" % (cls,)
ra = [(key, value) for key, value in cls.__dict__.items() if not key.startswith('_')]
for (k, v) in ra:
setattr(cls, "_"+k, v)
def get_a(cls):
print "Getting value of " + k
get_a(cls)
get_a.__name__ = "get_" + k
get_a.__doc__ = "Documentation for get_" + k
setattr(cls,get_a.__name__, get_a)
print get_a.__name__, get_a.__doc__
class BaseObject(object):
__metaclass__ = MetaClass
pass
And then :
class Pers(BaseObject):
nom = "Toune"
prenom = "Fabien"
p = Pers()
I was expecting to have two distinct functions "p.get_nom()" and "p.get_prenom()" Btw, those two functions return the same result ("Getting value of prenom"), whereas they have distinct name and doc
What am I missing ?
Upvotes: 2
Views: 403
Reputation: 601529
Change
def get_a(cls):
print "Getting value of " + k
to
def get_a(cls, k=k):
print "Getting value of " + k
to make this work. There is only one local variable k
, and the local function get_a()
will always access the current value of this variable. After finishing the loop, k
will keep its last value.
Upvotes: 2
Reputation: 798556
Ah yes, closures. Read that article then come back.
for (k, v) in ra:
setattr(cls, "_"+k, v)
def new_method(val):
def inner_get_a(cls):
print "Getting value of " + val
return inner_get_a
get_a = new_method(k)
get_a(cls)
get_a.__name__ = "get_" + k
get_a.__doc__ = "Documentation for get_" + k
setattr(cls,get_a.__name__, get_a)
print get_a.__name__, get_a.__doc__
Upvotes: 5