元类(metaclass)

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

type与object的关系详见:python中type和object

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.使用元类实现单例模式

 class SingletonMetaClass(type):
__instance = None def __call__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = super().__call__(*args, **kwargs)
print(cls.__instance)
return cls.__instance class Singleton(metaclass=SingletonMetaClass):
pass singleton1 = Singleton()
singleton2 = Singleton()
print(id(singleton1))
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中元类的更多相关文章

  1. python中元类(metaclass)的理解

    原文地址:http://www.cnblogs.com/tkqasn/p/6524879.html 一:类也是对象 类就是一组用来描述如何生成一个对象的代码. 类也是一个对象,只要你使用关键字clas ...

  2. 对python中元类的理解

    1. 类也是对象 在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Python中这一点仍然成立: >>> class ObjectCreator(object): ...

  3. 谈谈Python中元类Metaclass(一):什么是元类

    简单的讲,元类创建了Python中所有的对象. 我们说Python是一种动态语言,而动态语言和静态语言最大的不同,就是函数和类不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个HelloW ...

  4. 谈谈Python中元类Metaclass(二):ORM实践

    什么是ORM? ORM的英文全称是“Object Relational Mapping”,即对象-关系映射,从字面上直接理解,就是把“关系”给“对象”化. 对应到数据库,我们知道关系数据库(例如Mys ...

  5. python 通过元类控制类的创建

    一.python中如何创建类? 1. 直接定义类 class A: a = 'a' 2. 通过type对象创建 在python中一切都是对象 在上面这张图中,A是我们平常在python中写的类,它可以 ...

  6. 【转】Python 之 元类

    原文链接: https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python      http://python.jo ...

  7. 转---一文读懂 python 的元类

    译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得 ...

  8. Python 的元类设计起源自哪里?

    一个元老级的 Python 核心开发者曾建议我们( 点击阅读),应该广泛学习其它编程语言的优秀特性,从而提升 Python 在相关领域的能力.在关于元编程方面,他的建议是学习 Hy 和 Ruby.但是 ...

  9. Python中的类、对象、继承

    类 Python中,类的命名使用帕斯卡命名方式,即首字母大写. Python中定义类的方式如下: class 类名([父类名[,父类名[,...]]]): pass 省略父类名表示该类直接继承自obj ...

随机推荐

  1. HTTP连接池

    <context:property-placeholder location="classpath:conf/framework/httpclient.properties" ...

  2. IntelliJ IDEA插件 - ApiDebugger

    IntelliJ IDEA插件 - ApiDebuggerApiDebugger,是一个开源的接口调试IntelliJ IDEA插件,具有与IDEA一致的界面,无需切换程序即可完成网络API请求,让你 ...

  3. pod 使用详解

    cd 进去到 项目目录 包含 xcodeproj 结尾的目录下 1 pod init 创建一个pod 文件 2 打开生产的pod 文件 然后 配置pod 文件 并保存  3 pod install 安 ...

  4. 【Java】「深入理解Java虚拟机」学习笔记(4)- 类文件结构

    我为什么喜欢Java,另一个重要原因就是跨平台,WORA. 程序员是爽了,但肯定有人要为你遮风挡雨,解决WORA的基石就是字节码+虚拟机. ♣Tip 其实这里存在两种无关性,一是平台无关性.另一个是语 ...

  5. Java之递归方法的字符串回文问题

    日期:2018.10.12 星期五 博客期:018 题目: 题目分析:本题目因为是要求用递归的,所以大类里就写一个递归方法,在主方法里用字符串调用这个方法就好了!这是大致这个类的框架定位,然后定位我们 ...

  6. 声明寄存器ROM

    :] ROM [:] ; integer i; initial begin ;i<=;i=i+) begin ROM[i] <= {{'b0}}; end end 同时可以考虑双端口ROM ...

  7. ActiveMQ消息的消费原理

    消费端消费消息: 在 初识ActiveMQ 中我提到过,两种方法可以接收消息,一种是使用同步阻塞的ActiveMQMessageConsumer#receive方法.另一种是使用消息监听器Messag ...

  8. dubbo源码之服务消费

    消费端启动初始化过程: 消费端的代码解析也是从配置文件解析开始的,服务发布对应的<dubbo:service,解析xml的时候解析了一个ServiceBean,并且调用ServiceConfig ...

  9. 【linux】ftp使用端口转发问题

    相关资料: 1.[ssh]端口转发 2.[ftp]主动模式和被动模式 先说结论:用端口转发无法解决ftp客户端与服务器的连接问题,原因是ftp的data端口不固定,不能把所有>1024的端口都做 ...

  10. C和Java判断一个数字是否为素数

    C: /* 素数: 素数又称质数.所谓素数是指除了 1 和它本身以外,不能被任何整数整除的数,例如17就是素数,因为它不能被 2~16 的任一整数整除. */ # include <stdio. ...