元类(metaclass)

简单地说,元类就是一个能创建类的类,而类class 是由type创建的,class可以创建对象

1.type动态创建类:

def __init__(cls, what, bases=None, dict=None):

# known special case of type.__init__

"""

type(object_or_name, bases, dict)

type(object) -> the object's type

type(name, bases, dict) -> a new type

# (copied from class doc)

"""

pass

从type源码可以看出,type接受3个参数,第一个是要创建的类名,第二个参数是接受一个tuple(这个类所继承的基类),第三个参数接受一个dict(这个类的属性)

class BaseResource:

def check_resource(self):

return "base class"

def paper_edit(self):

return "edit paper..."

if __name__=="__main__":

Paper = type(

"Paper",

(BaseResource,),

{

"name":"paper_name",

"paper_edit":paper_edit

}

)

paper = Paper()

print(paper.check_resource())

print(paper.name)

print(paper.paper_edit())

result:

base class

paper_name

edit paper...

上例可以看到,使用type创建了Paper类,BaseResource是Paper的基类,paper有name属性和paper_edit方法

2.metaclass控制类对象的生成

对于python中类的实例化过程

(1). 首先寻找类中的metaclass

(2).如果找不到则找其父类的metaclass

(3).如果父类也找不到metaclass,则找其模块中的 如抽象类 找abc模块的 抽象类详见:Python抽象类

(4).在都找不到metaclass的情况下,使用type生成类

class BaseMetaClass(type):

def __new__(cls, name, bases, dict_agrs):

upper_dict = dict(

(arg_name.upper(), arg_val)

for arg_name, arg_val in dict_agrs.items()

)

return super().__new__(cls, name, bases, upper_dict)

class Paper(metaclass=BaseMetaClass):

name = "aaa"

print("hasattr(Paper, 'name'):{}".format(hasattr(Paper, 'name')))

print("hasattr(Paper, 'NAME'):{}".format(hasattr(Paper, 'NAME')))

BaseMetaClass的父类是type,实现了type的__new__方法,将type()方法的第三个参数(类的属性)做属性名大写转换, Paper类中定义了metaclass,在生成Paper类前会先去执行metaclass,即name="Paper" bases=() dict_agrs = {"name":"aaa"}, dict_agrs 执行大写转换后变成 {"NAME":"aaa"},即:Paper = type("Paper" ,() ,{"NAME":"aaa"})

result

hasattr(Paper, 'name'):False

hasattr(Paper, 'NAME'):True

3.使用元类实现单例模式

1 classSingletonMetaClass(type):2 __instance =None3

4 def __call__(cls, *args, **kwargs):5 if cls.__instance isNone:6 cls.__instance = super().__call__(*args, **kwargs)7 print(cls.__instance)8 return cls.__instance

9

10

11 class Singleton(metaclass=SingletonMetaClass):12 pass

13

14 singleton1 =Singleton()15 singleton2 =Singleton()16 print(id(singleton1))17 print(id(singleton2))

Singleton类在生成时先调用SingletonMetaClass,Singleton作为SingletonMetaClass的一个实例,

执行Singleton()时,会调用__call__方法(__call__让实例能像函数一样调用),__call__在Singleton类实例化(__new__和__init)之前调用,执行Singleton2时,直接返回之前存储在类属性cls._instance中的实例。

result

<__main__.Singleton object at 0x7fbd720fd978>

<__main__.Singleton object at 0x7fbd720fd978>

140451639187832

140451639187832

python元类_Python中元类相关推荐

  1. python如何定义类_python中定义类

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 类的定义python中,定义类是通过class关键字,例如我们定义一个存储学生信 ...

  2. python类_Python中的类

    Python和Java都是面向对象的语言,对象从类中获取,类指的是同一类具有相同特征的事物,比如拉布拉多,柯基,哈士奇,它们都是狗,具有狗的相同特征,所以可以被归为一类Dog,Python中类的使用与 ...

  3. python编写ATM类_Python中编写类的各种技巧和方法

    有关 Python 内编写类的各种技巧和方法(构建和初始化.重载操作符.类描述.属性访问控制.自定义序列.反射机制.可调用对象.上下文管理.构建描述符对象.Pickling).你可以把它当作一个教程, ...

  4. python3新式类_Python中新式类与经典类的区别详析

    1.新式类与经典类 在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于"新式类",都会获得所有"新式类"的 ...

  5. python经典类和新式类_python中经典类和新式类的区别

    在定义class的时候,有几种常见的写法,比如: class A: pass class B(): pass class C(object): pass 在python 2中查看以上各个class的类 ...

  6. python删除类方法_python中向类中动态添加新特性及删除属性方法

    class Foo(object): pass obj = Foo() # 添加对象属性(对象名追加对象属性) obj.a = 100 # print(obj.a) # 添加类属性(类名称追加类属性) ...

  7. python多分类_python中多类分类的ROC或CAP曲线

    要绘制多类ROC,请在类上使用label_binarize函数.在 使用虹膜数据的示例:import matplotlib.pyplot as plt from sklearn import svm, ...

  8. 标准布局类(11中布局类)

    2019独角兽企业重金招聘Python工程师标准>>> <div class="box"><div id="myAuto" ...

  9. python中的元类_python中的元类

    类也是对象,但是类有创建对象的能力 动态创建一个类: classmonkey():defbanana(self):print 'banana!' defapple(self):print 'i wan ...

  10. python元类_python中的元类 metaclass

    python中的元类 metaclass 在python中,类(class)本身也是一个实例对象, 它的类型则是元类, 如果没有指明, 则自定义类的类型是type. 换言之, 我们所定义的普通类都是t ...

最新文章

  1. mysql 1146错误
  2. C指针原理(39)-GLIB
  3. OpenCV 反投影Back Projection
  4. java国际化---native2ascii.exe 的使用方法
  5. 国际电汇的清算代码是什么?
  6. Nature官方劝退读博:全球七成博士对前途迷茫
  7. 计算机游戏高少手电影,支持switch,还有电影特技!上手简评骨伽IMMERSA Ti游戏耳机...
  8. java mvc mvvm_从MVC到MVVM(为什么要用vue)
  9. 闲谈IPv6-v4/v6协议转换报文的checksum无关性
  10. 如何在Visio中绘制KPT模型中的用户(小人)?在哪里找?
  11. spss数据的预处理
  12. 计算机网络组成两大部分组成,计算机网络的组成部分
  13. Docker容器运行
  14. 《亲自动手写一个深度学习框架》-专题视频课程-广州市老刘
  15. harmonyOS2,harmonyos2.0
  16. 计算机位置隐私保护的书,清华大学出版社-图书详情-《隐私保护数据发布:模型与算法》...
  17. webshell一句话
  18. matlab 类似宏定义,比较全面的宏定义解析
  19. 小程序自动化测试框架原理剖析
  20. 【源码】用主应力线(应力可视化)研究二维应力场

热门文章

  1. 使用DotNet以来一直都有出现这样的问题
  2. 4.性能之巅 洞悉系统、企业与云计算 --- 观测工具
  3. 14.UNIX 环境高级编程--高级IO
  4. 8. PHP7 安装
  5. 24.root, alias
  6. 2. wordpress 友情链接的备份和导入
  7. 51. PHP 页面静态化(4)
  8. 19. jQuery 遍历
  9. IOI2019团体总分前十排名:美国队夺魁,中国队第三,亚洲占六席
  10. Hibernate 继承映射可能会遇到的错误