简单定义元编程是一种编写计算机程序的技术, 这些程序可以将自己看做数据, 因此你可以在运行时对它进行内审生成和 / 或修改, 本博参考 <<Python 高级编程>> 将对元编程内容进行详细描述, 若有不正确之处希望大家指出
1. 概述
Python 元编程有两种方法, 一是采用类似装饰器的工具对基本元素 (例如函数类类型) 内审和对其进行实时创建和修改, 二是运用类型 "元类" 的方式对类实例的创建过程进行修改, 甚至于允许重新设计 Python 面对对象编程范式的实现
2. 装饰器
关于装饰器的内容可以阅读上篇博客<<Python 装饰器>>, 链接: http://www.cnblogs.com/xiaobingqianrui/p/8435074.html
对 wraps 装饰器的使用进行补充说明, 在类装饰器中使用闭包会导致生成的对象不再是被装饰的类的实例, 二是在装饰器函数创建的子类的实例, 这会影响__name__和__doc__等属性, 在上篇我们使用 @wraps 装饰器对函数装饰器进行操作让问题得到解决, 但在类装饰器中这一方法无效
3. 元类
元类是 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'>
3.1 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)
3.2 元类的常用模板
- #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_
用 class 语句创建的每个类都隐式的使用 type 作为元类, 可以用 metaclass = 指定元类的方式改变这一默认行为
3.3 元类的使用
元类是一种非常强大的特性, 但总是会是代码更加复杂, 将其用于任意类型的类时, 这可能会降低代码的鲁棒性, 我们必须灵活的使用元类
- #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__'])
来源: https://www.cnblogs.com/xiaobingqianrui/p/8435075.html