Metaclass中的动态函数创建

时间:2011-11-15 15:31:30

标签: python

我正在Python 2.7 Metaprogramming中完成我的第一步,并编写了以下代码:

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

然后:

class Pers(BaseObject):
    nom = "Toune"
    prenom = "Fabien"

p = Pers()

我希望有两个不同的函数“p.get_nom()”和“p.get_prenom()” 顺便说一句,这两个函数返回相同的结果(“获取prenom的值”),而它们有不同的名称 doc

我错过了什么?

2 个答案:

答案 0 :(得分:5)

啊,是的,closures。阅读那篇文章,然后回来。

    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__

答案 1 :(得分:2)

更改

def get_a(cls):
    print "Getting value of " + k

def get_a(cls, k=k):
    print "Getting value of " + k

使这项工作。只有一个局部变量k,本地函数get_a()将始终访问此变量的当前值。完成循环后,k将保留其最后一个值。