什么是元编程
软件开发中很重要的一条原则就是“不要重复自己的工作(Don’t repeat youself)”,也就是说当我们需要复制粘贴代码时候,通常都需要寻找一个更加优雅的解决方案,在python中,这类问题常常会归类为“元编程”
元编程目的
是创建函数和类,并用他们操作代码(例如修改,生成,或者包装自己已有的代码)。尽可能的使代码优雅简洁。具体而言,通过编程的方法,在更高的抽象层次上对一种层次的抽象的特性进行修改
元编程应用
给函数添加一个包装(装饰器)
注意:对wraps装饰器的使用进行补充说明,在类装饰器中使用闭包会导致生成的对象不再是被装饰的类的实例,而是在装饰器函数创建的子类的实例,这会影响__name__和__doc__等属性,在上篇我们使用@wraps装饰器对函数装饰器进行操作让问题得到解决,但在类装饰器中这一方法无效。
元类
在理解元类之前,您需要掌握Python中的类。Python对于从Smalltalk语言借用的类是非常奇怪的。在大多数语言中,类只是描述如何生成对象的代码片段。在Python中也是如此:
1 2 3 4 5 6 7 |
>>> class ObjectCreator( object ): ... pass ... >>> my_object = ObjectCreator() >>> print(my_object) <__main__.ObjectCreator object at 0x8974f2c> |
一旦使用关键字class
,Python就会执行它并创建一个OBJECT。指示
1 2 3 |
>>> class ObjectCreator( object ): ... pass ... |
在内存中创建一个名为“ObjectCreator”的对象。这个对象(类)本身能够创建对象(实例),这就是为什么它是一个类。但是,它仍然是一个对象,因此:
-
- 您可以将其分配给变量
- 你可以复制它
- 你可以添加属性
- 您可以将其作为函数参数传递
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
>>> print(ObjectCreator) # you can print a class because it's an object < class '__main__.ObjectCreator' > >>> def echo(o): ... print(o) ... >>> echo(ObjectCreator) # you can pass a class as a parameter < class '__main__.ObjectCreator' > >>> print(hasattr(ObjectCreator, 'new_attribute' )) False >>> ObjectCreator.new_attribute = 'foo' # you can add attributes to a class >>> print(hasattr(ObjectCreator, 'new_attribute' )) True >>> print(ObjectCreator.new_attribute) foo >>> ObjectCreatorMirror = ObjectCreator # you can assign a class to a variable >>> print(ObjectCreatorMirror.new_attribute) foo >>> print(ObjectCreatorMirror()) <__main__.ObjectCreator object at 0x8997b4c> |
动态创建类
由于类是对象,因此您可以像任何对象一样动态创建它们。首先,您可以使用class
以下命令在函数中创建类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
>>> def choose_class(name): ... if name == 'foo' : ... class Foo( object ): ... pass ... return Foo # return the class , not an instance ... else : ... class Bar( object ): ...
|