python type metaclass
在python中一切皆对象, 所有类的鼻祖都是type, 也就是所有类都是通过type来创建。
传统创建类
class Foo(object):
def __init__(self,name):
self.name = name f = Foo("shuaigaogao")
f 是通过 Foo 类实例化的对象,其实,不仅 f 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象,按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。
print(type(f)) #输出:<class '__main__.Foo'> 表示:f 对象由Foo类创建print(type(Foo)) #输出:<class 'type'> 表示:Foo类对象由 type 类创建type创建类
def func(self): #创建方法
print("hello {0}".format(self.name)) def __init__(self,name): #创建构造方法
self.name = name Foo = type("Foo",(object,),{"talk":func,"__init__":__init__}) #通过type创建类,如果是经典类的话则写成:Foo = type("Foo",(),{"talk":func,"__init__":__init__})
f = Foo("shuaigaogao") #创建对象
f.talk() #输出
hello shuaigaogao
总结:类 是由 type 类 实例化产生的
__new__方法
new方法是类自带的一个方法,可以重构,__new__方法在实例化的时候也会执行,并且先于__init__方法之前执行.
class Foo(object):
def __init__(self,name):
self.name = name
print("Foo __init__")
def __new__(cls, *args, **kwargs):
print("Foo __new__",cls, *args, **kwargs)
return object.__new__(cls)
f = Foo("shuaigaogao")
#输出
Foo __new__ <class '__main__.Foo'> shuaigaogao #执行了new方法
Foo __init__ #执行了__init__方法
new方法作用
作用:所有对象都是通过new方法来实例化的,new里面调用了init方法,所以在实例化的过程中先执行的是new方法,而不是init方法。
①重构__new__方法
class Foo(object):
def __init__(self,name):
self.name = name
print("Foo __init__")
def __new__(cls, *args, **kwargs):
print("Foo __new__",cls, *args, **kwargs)
f = Foo("shuaigaogao") #实例化
#输出
Foo __new__ <class '__main__.Foo'> shuaigaogao
由上面的例子看出,没有执行__init__方法
②重构__new__方法,并继承父类的__new__方法
class Foo(object):
def __init__(self,name):
self.name = name
print("Foo __init__")
def __new__(cls, *args, **kwargs): #cls相当于传入类Foo
print("Foo __new__",cls, *args, **kwargs)
return object.__new__(cls) #继承父类的__new__方法,这边必须以返回值的形式继承
f = Foo("shuaigaogao")
#输出
Foo __new__ <class '__main__.Foo'> shuaigaogao
Foo __init__
由上面不难看出,大多数情况下,你都不要去重构你的__new__方法,因为你父类中已经有__new__方法了,已经帮你写好了怎么去创建类,如果你重写的话,就会覆盖父类的里面的__new__方法。但是你重构可以增加一点小功能,但是你覆盖了以后还是需要继承父类回来,要不然你的这个实例就创建不了。
使用场景
我想对我自己写的一些类进行定制,就在它实例化之前就进行定制,就可以用到__new__方法,new方法就是用来创建实例的,重构new方法,必须以返回值的形式继承父类的new方法。
①需求:我在创建对象时候,同时创建一个类变量
class Foo(object):
def __init__(self,name):
self.name = name
print("Foo __init__")
def __new__(cls, *args, **kwargs): #cls相当于是传入的类名Foo
cls.name = "shuaigaogao" #创建对象是定义静态变量
print(cls.name)
return object.__new__(cls) #继承父类的__new__方法
f = Foo("shuaigaogao")
print(Foo.name)
__metaclass__方法
metaclass作用
类 是由 type 类实例化产生
那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?
答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。
class MyType(type):
def __init__(self,*args,**kwargs): print("Mytype __init__",*args,**kwargs) def __call__(self, *args, **kwargs):
print("Mytype __call__", *args, **kwargs)
obj = self.__new__(self)
print("obj ",obj,*args, **kwargs)
print(self)
self.__init__(obj,*args, **kwargs)
return obj def __new__(cls, *args, **kwargs):
print("Mytype __new__",*args,**kwargs)
return type.__new__(cls, *args, **kwargs) print('here...')
class Foo(object,metaclass=MyType): def __init__(self,name):
self.name = name print("Foo __init__") def __new__(cls, *args, **kwargs):
print("Foo __new__",cls, *args, **kwargs)
return object.__new__(cls) f = Foo("Alex")
print("f",f)
print("fname",f.name)
执行顺序
类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__
https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python
传统创建类
python type metaclass的更多相关文章
- Python type class metaclass
'type' 是 python built-in metaclass 其他继承自 ‘type’的class都可以是 Metaclass 子类可以继承父类的metaclass 然而 __metaclas ...
- Python魔法 - MetaClass
Python魔法 - MetaClass metaclass The class of a class. Class definitions create a class name, a class ...
- python's metaclass
[python's metaclass] 和objc中类似,metaclass用于创建一个类对象,但与objc不同的是,objc中每个类对象有各自不同的metaclass,而python中的metac ...
- Python type类具体的三大分类:metaclasses,classes,instance
Python type类视角中的对象体系需要我们不断的学习,其中我们使用的时候需要注意.下面我们就看看如何才能更好的运用Python type类.下面的文章希望大家有所收获. 在单纯的Python t ...
- 使用python type动态创建类
使用python type动态创建类 X = type('X', (object,), dict(a=1)) # 产生一个新的类型 X 和下列方法class X(object): a = 1效 ...
- Python Type Hint类型注解
原文地址:https://realpython.com/python-type-checking/ 在本指南中,你将了解Python类型检查.传统上,Python解释器以灵活但隐式的方式处理类型.Py ...
- python——type()、metaclass元类和精简ORM框架
1.type()函数 if __name__ == '__main__': h = hello() h.hello() print(type(hello)) print(type(h)) Hello, ...
- python 元类 type metaclass
python中一切皆对象,类对象创建实例对象,元类创建类对象,元类创建元类. 元类创建类对象有2中方式: 一.type方法 type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属性 ...
- Python面向对象 -- slots, @property、多重继承MixIn、定制类(str, iter, getitem, getattr, call, callable函数,可调用对象)、元类(type, metaclass)
面向对象设计中最基础的3个概念:数据封装.继承和多态 动态给class增加功能 正常情况下,当定义了一个class,然后创建了一个class的实例后,可以在程序运行的过程中给该实例绑定任何属性和方法, ...
随机推荐
- oracle创建/删除表空间、创建/删除用户并赋予权限
创建表空间 分开执行如下sql语句 --创建临时表空间 CREATE SMALLFILE TEMPORARY TABLESPACE "TEMP11" TEMPFILE 'E:\ap ...
- HDOJ-1124 Factorial 数论
题意哇:求N!末尾多少个0. 很容易想到转化为求N!中5因子的个数.但是从数据范围来看必然不可能一个一个算出来. 所以这里借用数论的一个知识. 如果p是素数,那么n!中p因子的个数可以表示为1-n中整 ...
- C++面试问题详解
1.定义一个全局变量放在.cpp文件还是.h文件,原因是什么 在cpp文件中定义变量,h文件用来声明变量的作用域,使用extern声明的变量可以在本编译单元或其他编译单元中使用. 举例如下: a.h文 ...
- POJ-1160 Post Office (DP+四边形不等式优化)
题目大意:有v个村庄成直线排列,要建设p个邮局,为了使每一个村庄到离它最近的邮局的距离之和最小,应该怎样分配邮局的建设,输出最小距离和. 题目分析:定义状态dp(i,j)表示建设 i 个邮局最远覆盖到 ...
- Oracle11g温习-第七章:redo日志
2013年4月27日 星期六 10:33 1.redo (重做) log 的功能: 用于数据恢复 2.redo log 特征: [特征]: 1) 记录数据块的变化(DML.D ...
- ABAP基础二:ALV基础之ALV的简单编辑
前两天有个打印需求变更,需要在ALV显示列表中添加两个字段,可编辑,而我自己用的是函数:REUSE_ALV_GRID_DISPLAY_LVC 因为之前做可编辑基本都是固定套路,定义类,画屏幕.... ...
- Linux磁盘管理,vi编辑器以及包管理器
一.Linux磁盘管理 Linux磁盘管理常用的三个命令为df,du,fdisk df:列出文件系统的整体磁盘使用量,利用这个命令来获取磁盘被占用了多少空间,,目前还剩下多少空间用法:df [-ahi ...
- springmvc基础流程
转载:http://blog.csdn.net/zuoluoboy/article/details/19766131 注意:springmvc多个拦截器执行流程:每个拦截器的方法preHandler顺 ...
- 组数排序非sort
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...
- matplotlib小示例
matplotlib 画廊 http://matplotlib.org/gallery.html import numpy as np import matplotlib.pyplot as plt ...