简单定义“元编程是一种编写计算机程序的技术,这些程序能够将本身看作数据,所以你能够在运行时对它进行内审、生成和/或修改”,本博参考<<Python高级编程>>将对元编程内容进行详细描述,如有不正确之处但愿你们指出。
Python元编程有两种方法,一是采用相似“装饰器”的工具对基本元素(例如函数、类、类型)内审和对其进行实时建立和修改,二是运用类型"元类"的方式对类实例的建立过程进行修改,甚至于容许从新设计Python面对对象编程范式的实现。html
关于装饰器的内容能够阅读上篇博客<<Python装饰器>>,连接:http://www.cnblogs.com/xiaobingqianrui/p/8435074.html编程
对wraps装饰器的使用进行补充说明,在类装饰器中使用闭包会致使生成的对象再也不是被装饰的类的实例,二是在装饰器函数建立的子类的实例,这会影响__name__和__doc__等属性,在上篇咱们使用@wraps装饰器对函数装饰器进行操做让问题获得解决,但在类装饰器中这一方法无效。
元类是Python的一个重要特性,是定义其余类的类,理解其工做方式,最重要的是要知道定义了对象实例的类也是对象,那么它必定有与其相关联的类,全部的类定义的基类都是内置的type类。闭包
#coding=utf-8 class MyClass: pass if __name__ == "__main__": myclass = MyClass() print ("type of myclass:", type(myclass)) print ("type of MyClass:", type(MyClass))
>>> type of myclass: <class '__main__.MyClass'>
>>> type of MyClass: <class 'type'>函数
type()类做为class语句的动态等效,给定类名,基类名和属性映射会建立一个新类 工具
#coding=utf-8 def func1(self): print (1) def func2(*argv): print (argv) if __name__ == "__main__": MyClass = type("MyClass",(object, ), {"func1":func1, "func2":func2}) a = MyClass() print (type(a)) a.func1() a.func2(2)
>>> <class '__main__.MyClass'>
>>> 1
>>> (<__main__.MyClass object at 0x01A02270>,2)ui
#coding=utf-8 '''元类模板 ''' class MyClass(type): #建立一个空的命名空间,返回一个空的dict @classmethod def __prepare__(mcs, name, bases, **kwargs): print ("MyClass __prepare__") return super().__prepare__(name, bases, **kwargs) def __new__(mcs, name, bases, namespace): print ("MyClass __new__") return super().__new__(mcs, name, bases, namespace) def __init__(cls, name, bases, namespace, **kdargv): print ("MyClass __init__") super().__init__(name, bases, namespace) def __call__(cls, *argv, **kdargv): print ("MyClass __call__") return super().__call__(*argv, **kdargv) class _MyClass(metaclass=MyClass): def __new__(cls): print ("_MyClass __new__") return super().__new__(cls) def __init__(self): print("__MyClass __init__") super().__init__() if __name__ == "__main__": a = _MyClass()
>>> MyClass __prepare__
>>> MyClass __new__
>>> MyClass __init__
>>> MyClass __call__
>>> _MyClass __new__
>>> __MyClass __init_spa
用class语句建立的每一个类都隐式的使用type做为元类,能够用metaclass=“指定元类”的方式改变这一默认行为。
元类是一种很是强大的特性,但老是会是代码更加复杂,将其用于任意类型的类时,这可能会下降代码的鲁棒性,咱们必须灵活的使用元类。设计
#coding=utf-8 class OrderedMeta(type): @classmethod def __prepare__(mcs, name, bases, **kdargv): return super().__prepare__(mcs, name, bases, **kdargv) def __new__(mcs, name, bases, namespace): namespace["orderofattr"] = list(namespace.keys()) return super().__new__(mcs, name, bases, namespace) class test(metaclass = OrderedMeta): first = 8 secord = 2 if __name__ == "__main__": print (test.orderofattr) print (test.__dict__.keys())
>>> ['__module__', '__qualname__', 'first', 'secord']
>>> dict_keys(['__module__', 'first', 'secord', 'orderofattr', '__dict__', '__weakre
>>> f__', '__doc__'])code