博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python-元编程
阅读量:4550 次
发布时间:2019-06-08

本文共 4979 字,大约阅读时间需要 16 分钟。

1、元编程:

  元编程 概念来自 LISP 和 smalltalk

  我们写程序 是直接写代码,是否能够用代码来生成未来我们需要的代码,这就是元编程。

  用阿里生成代码的程序称为元程序,metaprogram,编写这种程序就称为元编程。

  Python 语言能够通过反射实现 元编程

  

  python 中;

    所有非object 类都继承自object 类

    所有类的类型包括 type类 都是type

    type类 继承自object 类,object类的类型也是type类

2、type类

  type构建类: 

1 class type(object):2     """3     type(object_or_name, bases, dict)4     type(object) -> the object's type  ----> 返回对象的类型,例如 type(10)5     type(name, bases, dict) -> a new type ----> 返回一个新的类型6     """

 

  测试:

1 XClass = type('mycalss', (object,), {
'a':100, 'b':'string'})2 3 print(XClass)4 print(XClass.__dict__)5 print(XClass.__name__)6 print(XClass.__bases__)7 print(XClass.mro())

 

  结果:

{
'a': 100, 'b': 'string', '__module__': '__main__', '__dict__':
, '__weakref__':
, '__doc__': None}mycalss(
,)[
,
]

 

   mycalss 是创建类的 标识符

  (objects,): 基类

  类似命名元组

  

  测试:

1 def __init__(self): 2     self.x = 100 3  4 def show(self): 5     print(self.__dict__) 6     print(self.x) 7  8 XClass = type('myclass', (object,), {
'a':100,'b':111, 'show':show, '__init__':__init__}) 9 10 print(XClass)11 print(XClass.__name__)12 print(XClass.__dict__)13 print(XClass.mro())14 15 print('-' * 40)16 XClass().show()

 

  结果:

1 
2 myclass3 {
'a': 100, 'b': 111, 'show':
, '__init__':
, '__module__': '__main__', '__dict__':
, '__weakref__':
, '__doc__': None}4 [
,
]5 ----------------------------------------6 { 'x': 100}7 100

  可以借助type 构造 任何类,用代码来生成代码,这就是元 编程

 

3、构造元类:

  一个类可以继承自type 类,注意不是继承自 object 类了。

1 class ModelMeta(type): 2     def __new__(cls, *args, **kwargs): 3         print(cls) 4         print(args) # 就是 type(name,bases, dict)的参数 5         print(kwargs) 6         print('------------------------------') 7         return super().__new__(cls, *args, **kwargs) 8 # 此处的 ModelMeta 就是元类,继承自type,它可以创建出其他类 9 10 # 第一种 使用metaclass 关键字 参数指定元类11 class A(metaclass=ModelMeta):12     id = 10013 14     def __init__(self):15         print(' ==== A ====')16 print(A.__class__)17 print(A.mro())18 print('~~~~~~~~~~~~~~====~~~~~~~~~~')19 # 第二种 B继承自 A 后,依然是从ModelMeata的类型20 class B(A):21     def __init__(self):22         print('==== B ====')23 24 print(B.__class__)25 print(B.mro())26 print('~~~~~~~~~~~~====~~~~~~~~~~~~')27 # 第三种 元类就可以使用下面的方式创建新的类28 C = ModelMeta('C', (), {})29 print(C.__class__)30 print(C.mro())31 print('~~~~~~~~~~~~====~~~~~~~~~~~~')32 33 # D,E 是type的 实例, 没有使用自定义的元类,所以默认使用type34 class D:pass35 E = type('E', (), {})36 37 class F(ModelMeta):pass # 和A  不一样,没有使用关键字 metaclass38 39 print('=============================')40 print(type(A), A.__bases__)41 print(type(B), B.__bases__)42 print(type(C))43 print(type(D))44 print(type(E))45 print(type(F), F.__bases__)

 

  结果:

1 D:\python3.7\python.exe E:/code_pycharm/test_in_class/tt14.py 2 
3 ('A', (), {
'__module__': '__main__', '__qualname__': 'A', 'id': 100, '__init__':
}) 4 {} 5 ------------------------------ 6
7 [
,
] 8 ~~~~~~~~~~~~~~====~~~~~~~~~~ 9
10 ('B', (
,), { '__module__': '__main__', '__qualname__': 'B', '__init__':
})11 {}12 ------------------------------13
14 [
,
,
]15 ~~~~~~~~~~~~====~~~~~~~~~~~~16
17 ('C', (), {})18 {}19 ------------------------------20
21 [
,
]22 ~~~~~~~~~~~~====~~~~~~~~~~~~23 =============================24
(
,)25
(
,)26
27
28
29
(
,)30 31 Process finished with exit code 0

 

  修改代码如下:

1 class ModelMeta(type): 2     def __new__(cls, name, bases, dict): 3         print(cls) 4         print(name) 5         print(dict) 6         print('------------------------------') 7         return super().__new__(cls, name, bases, dict) 8 # 此处的 ModelMeta 就是元类,继承自type,它可以创建出其他类 9 10 # 第一种 使用metaclass 关键字 参数指定元类11 class A(metaclass=ModelMeta):12     id = 10013 14     def __init__(self):15         print(' ==== A ====')

   从结果看出,只要元类是ModelMeta,创建类对象时,就会调用MoelMeta的 __new__方法

 

元类的应用:

  模拟创建表格式

1 class Field:# 定义字段的属性类 2     def __init__(self, fieldname=None,pk=False, nullable=True): 3         self.fieldname= fieldname 4         self.pk = pk 5         self.nullable = nullable 6  7     def __repr__(self): 8         return '

 

  结果:

1 D:\python3.7\python.exe E:/code_pycharm/test_in_class/tt14.py 2 
3 ModelBase 4 () 5 ===== {
'__module__': '__main__', '__qualname__': 'ModelBase', '__doc__': ' 从 ModelBases 继承的类的类型都是ModelMeta '} ===== 6
7 Students 8 (
,) 9 ===== {
'__module__': '__main__', '__qualname__': 'Students', 'id':
View Code

 

 

元编程总结:

  元类是制造类的工厂,是生成类的类

  构造好元类,就可以在类定义的时候,使用关键字参数 metaclass 指定元类,可以使用最原始的metatype(name,base,dict)的方式 构造一个类

  元类的__new__()方法中,可以获取元类的信息,当前类,基类,类属性字典

  

  元编程一般用于框架开发中,Django SQLAlchemy 都使用了 元类。

 

转载于:https://www.cnblogs.com/JerryZao/p/9938976.html

你可能感兴趣的文章
Java冒泡排序与二分法查找的代码随笔
查看>>
理解javascript观察者模式(订阅者与发布者)
查看>>
使用cocostudio 需要在Android.mk文件的配置
查看>>
WPF换肤之二:可拉动的窗体
查看>>
Lambda表达式
查看>>
VS2012智能感知变英文解决办法
查看>>
Python3中的赋值操作、浅拷贝与深拷贝
查看>>
多级字典表单的Python实现
查看>>
常用正则
查看>>
rvm的使用
查看>>
4.3 高级特性(3) -- 过滤
查看>>
MongoDB C++ 2.4.5 driver 编译安装问题
查看>>
非结构化数据存储方案
查看>>
Java非静态代码块和静态代码块
查看>>
FactoryBean的实现原理与作用
查看>>
HTML 中 id与name 区别
查看>>
[iOS]提交App报错ERROR ITMS -90207
查看>>
javascript高级编程 小示例
查看>>
楼层扔鸡蛋问题
查看>>
最后一节课 12-27
查看>>