python 通过元类控制类的创建
一、python中如何创建类?
1. 直接定义类
class A:
a = 'a'
2. 通过type对象创建
在python中一切都是对象
在上面这张图中,A是我们平常在python中写的类,它可以创建一个对象a。其实A这个类也是一个对象,它是type类的对象,可以说type类是用来创建类对象的类,我们平常写的类都是type类创建的对象,再由创建的对象再去创建我们平常使用的对象,我们可以看看type的官方文档
type(object_or_name, bases, dict)
type(object) -> the object's type
type(name, bases, dict) -> a new type
type有另一种用法type(name, bases, dict)来创建类 中,name是这个类的名字,bases是这个类的基类(是一个元组),dict是这个类的属性(是一个字典),我们通过type实现上面的例子中A类的创建
A = type('A', (), {'a': 'a'})
二、什么是元类编程?
我们已经知道,类也是对象,那么我们在创建类的时候,可不可以控制类的创建过程?当然是可以的,这就是元类编程。
三、如何实现元类编程?
1. 在要定义的类中使用__new__方法
class A:
def __new__(cls, *args, **kwargs):
cls.a = 'a'
return super().__new__(cls, *args, **kwargs)
这样就实现了创建A类的时候,添加了一个类属性a(注意的是,__new__方法要返回一个创建的对象,当然,我们也可以返回其他东西;另一个注意点是__new__方法要在实例化的时候才会运行,所以,类属性a必须是在A实例化后才会出现)
2. 使用metaclass关键字,使用metaclass关键字的时候,我们要定义一个type类
class B(type):
def __init__(self, *args, **kwargs):
self.a = 'a'
super().__init__(*args, **kwargs) class A(metaclass=B):
pass
我们定义了一个B类继承type,在A类创建的时候传递关键字metaclass=B,就会执行B类种的代码,控制A类的创建,这个例子也是为A类添加了一个类属性a。我们还可以在B类中使用__init__,__call__方法。
四、python中元类编程执行的顺序
class MetaClass(type):
# 定义A类的时候就会调用
def __init__(self, *args, **kwargs):
print('MetaClass __init__')
super().__init__(*args, **kwargs) # 定义A类的时候,就会调用
def __new__(cls, *args, **kwargs):
print('MetaClass __new__')
# *args 里面包含了创建A类的参数
return super().__new__(cls, *args, **kwargs) # A实例化的时候才会去调用call
def __call__(self, *args, **kwargs):
print('MetaClass __call__')
# 这儿其实是去调用A类需要实例化的所有方法
return super().__call__(*args, **kwargs) class A(metaclass=MetaClass):
def __init__(self):
print('A __init__') def __new__(cls, *args, **kwargs):
print('A __new__')
return super().__new__(cls, *args, **kwargs) a = A() # 输出
MetaClass __new__
MetaClass __init__
MetaClass __call__
A __new__
A __init__
五、总结
使用元类编程可以让我们在创建类的时候,给类添加一些额外的信息。但元类编程是python中难以理解的地方之一,而且工作中,大部分时候都是不会用到的,我们普通的类定义方式就可以解决问题了,若果说有99%的时候你需要控制创建类的过程,那就使用元类编程吧。
理解元类,大家可以参考这篇文章 what are metaclass in python?
python 通过元类控制类的创建的更多相关文章
- Day 5-8 自定义元类控制类的实例化行为
__call__方法: 对象后面加括号,触发执行. 注:构造方法的执行是由创建对象触发的,即:对象 = 类名() :而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类( ...
- Python之元类详细解析
一.补充内置函数isinstance和issubclass 1.isinstance是判断一个对象是不是由一个对象产生的 class Foo: pass obj=Foo() print(isinsta ...
- Python之元类详解
一.引子 元类属于Python面向对象编程的深层魔法,99%的人都不得要领,一些自以为搞明白元类的人其实也是自圆其说,点到为止,从队元类的控制上来看就破绽百出,逻辑混乱: 二.什么是元类 一切源自于一 ...
- python 之元类
定义类的两种方法: 1.class定义 2.type(类名,类的基类们,类的名称空间) # 定义类的三要素:类名.基类.名称空间 class_name = 'Chinese' class_bases ...
- 类和对象的创建过程(元类,__new__,__init__,__call__)
一. type() 1.创建类的两种方式 方式一 class MyClass(object): def func(self,name): print(name) myc = MyClass() pri ...
- 【转】Python 之 元类
原文链接: https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python http://python.jo ...
- Python中元类
元类(metaclass) 简单地说,元类就是一个能创建类的类,而类class 是由type创建的,class可以创建对象 type与object的关系详见:python中type和object 1. ...
- 转---一文读懂 python 的元类
译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得 ...
- python基础----元类metaclass
1 引子 class Foo: pass f1=Foo() #f1是通过Foo类实例化的对象 python中一切皆是对象,类本身也是一个对象,当使用关键字class的时候,python解释器在加载cl ...
随机推荐
- [Swift]LeetCode815. 公交路线 | Bus Routes
We have a list of bus routes. Each routes[i]is a bus route that the i-th bus repeats forever. For ex ...
- 巡风源码阅读与分析---nascan.py
Nascan是巡风主要是做目标的资产识别(信息收集). nascan.py 文件位于 nascan/nascan.py # coding:utf-8 # author:wolf@YSRC import ...
- ubuntu18下安装docker
1.通过指令检查linux内核 uname -a 可以看到大于3.10版本 2.检查是否存在对应目录 ls -l /sys/class/misc/device-mapper 3. apt-get指令 ...
- Python内置函数(57)——setattr
英文文档: setattr(object, name, value) This is the counterpart of getattr(). The arguments are an object ...
- Shader 入门笔记(一) 如何学习shader
本笔记,是根据自己学习shader的笔记,主要是参照冯乐乐的<Shader 入门精要> 和游戏蛮牛shaderLad视频 和网上一些博客. 为啥要学习这个呐? 自己其实之前学过一段时间的s ...
- Android--Tween补间动画
前言 Android除了支持逐帧动画之外,也提供了对补间动画的支持,补间动画就是指开发人员只需要指定动画的开始.动画结束的"关键帧",而动画变化的"中间帧"由系 ...
- Java基础7:关于Java类和包的那些事
更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...
- nginx~linux下的部署
一些概念 Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由Igor Sysoev为俄 ...
- Asp.Net SignalR - 准备工作
实时通讯 在做Web的时候经常会有客户端和服务端实时通讯的需求,比如即时聊天等.目前实时通讯有很多种规范和实现方式,但是每一个对浏览器的兼容性或者性能都不是很完美. 目前主流的解决方案有 WebSoc ...
- Node.js 进程平滑离场剖析
本文由云+社区发表 作者:草小灰 使用 Node.js 搭建 HTTP Server 已是司空见惯的事.在生产环境中,Node 进程平滑重启直接关系到服务的可靠性,它的重要性不容我们忽视.既然是平滑重 ...