今天好好琢磨一下 python 创建实例的先后顺序

一、 就定义一个普通类 Util (默认)继承自 object,覆写 new ,init 方法

class Util(object):
def __new__(cls,*args,**kw):
print('-----Util----__new__ ----start---')
print('cls: {}'.format(cls))
print('args: {}'.format(args))
{print('kw:',key,'<--->',value,'\n') for key,value in kw.items()}
return object.__new__(cls) def __init__(self,*args,**kw):
print('-----Util----__init__ ----start---')
print('self: {}'.format(self))
print('args: {}'.format(args))
{print(key,'<--->',value,'\n') for key,value in kw.items()}
return super(Util,self).__init__()
args =(1,2,3)
kw = dict(name='frank',city='changsha')
util = Util(*args,**kw)
print(util)
输出结果:
-----Util----__new__ ----start---
cls: <class '__main__.Util'>
args: (1, 2, 3)
kw: name <---> frank kw: city <---> changsha -----Util----__init__ ----start---
self: <__main__.Util object at 0x7f4d54082a90>
args: (1, 2, 3)
name <---> frank city <---> changsha <class '__main__.Util'>

由上面可以知道 new 优先于 init 执行,如果 __new__ 中没有 return 语句,则不会执行object 的 new 方法,而 init 在 object 中是在 new 中调用的,所以,此刻如下图, Util 中的 init 并不会被调用,只是调用了 Util 类的 new 方法,打印type(util) 得到的是 类类型 --》 NoneType ! 因为 构造方法init 没有被调用,也能理解还没有变为对象啊!!!

class Util(object):
def __new__(cls,*args,**kw):
print('-----Util----__new__ ----start---')
print('cls: {}'.format(cls))
print('args: {}'.format(args))
{print('kw:',key,'<--->',value,'\n') for key,value in kw.items()}
# return object.__new__(cls) def __init__(self,*args,**kw):
print('-----Util----__init__ ----start---')
print('self: {}'.format(self))
print('args: {}'.format(args))
{print(key,'<--->',value,'\n') for key,value in kw.items()}
return super(Util,self).__init__() args =(1,2,3)
kw = dict(name='frank',city='changsha')
util = Util(*args,**kw)
print(type(util))
结果:
-----Util----__new__ ----start---
cls: <class '__main__.Util'>
args: (1, 2, 3)
kw: name <---> frank kw: city <---> changsha <class 'NoneType'>

接下来,我们给Util 添加元类,由下图可以看出元类优先于Util 所有方法执行

class UtilMetaclass(type):
def __new__(meta_cls,cls,bases,attr_dict):
print('------UtilMetaclass---__new__ ---start----')
print('meta_cls: {}'.format(meta_cls))
print('cls: {}'.format(cls))
print('bases:{}'.format(bases))
print('attr_dict: {}\n'.format(attr_dict))
return type.__new__(meta_cls,cls,bases,attr_dict) # def __init__(self,*args,**kw):
# print('-----UtilMetaclass----__init__ ----start---')
# print('self: {}'.format(self))
# print('args: {}\n'.format(args))
# {print('kw:',key,'<--->',value,'\n') for key,value in kw.items()}
# return super(UtilMetaclass,self).__init__(*args,**kw) class Util(object,metaclass=UtilMetaclass):
def __new__(cls,*args,**kw):
print('-----Util----__new__ ----start---')
print('cls: {}'.format(cls))
print('args: {}'.format(args))
{print('kw:',key,'<--->',value,'\n') for key,value in kw.items()}
return object.__new__(cls) def __init__(self,*args,**kw):
print('-----Util----__init__ ----start---')
print('self: {}'.format(self))
print('args: {}'.format(args))
{print(key,'<--->',value,'\n') for key,value in kw.items()}
return super(Util,self).__init__() args =(1,2,3)
kw = dict(name='frank',city='changsha')
util = Util(*args,**kw)
print(type(util)) 输出结果:
------UtilMetaclass---__new__ ---start----
meta_cls: <class '__main__.UtilMetaclass'>
cls: Util
bases:(<class 'object'>,)
attr_dict: {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d540e99d8>, '__new__': <function Util.__new__ at 0x7f4d540e9ea0>} -----Util----__new__ ----start---
cls: <class '__main__.Util'>
args: (1, 2, 3)
kw: name <---> frank kw: city <---> changsha -----Util----__init__ ----start---
self: <__main__.Util object at 0x7f4d5409cb70>
args: (1, 2, 3)
name <---> frank city <---> changsha <class '__main__.Util'>

最后我们来看看给 元类 覆写掉其父类 type 的构造方法,却注释掉return super 语句

class UtilMetaclass(type):
def __new__(meta_cls,cls,bases,attr_dict):
print('------UtilMetaclass---__new__ ---start----')
print('meta_cls: {}'.format(meta_cls))
print('cls: {}'.format(cls))
print('bases:{}'.format(bases))
print('attr_dict: {}\n'.format(attr_dict))
return type.__new__(meta_cls,cls,bases,attr_dict) def __init__(self,*args,**kw):
print('-----UtilMetaclass----__init__ ----start---')
print('self: {}'.format(self))
print('args: {}\n'.format(args))
{print('kw:',key,'<--->',value,'\n') for key,value in kw.items()}
#return super(UtilMetaclass,self).__init__(*args,**kw) class Util(object,metaclass=UtilMetaclass):
def __new__(cls,*args,**kw):
print('-----Util----__new__ ----start---')
print('cls: {}'.format(cls))
print('args: {}'.format(args))
{print('kw:',key,'<--->',value,'\n') for key,value in kw.items()}
return object.__new__(cls) def __init__(self,*args,**kw):
print('-----Util----__init__ ----start---')
print('self: {}'.format(self))
print('args: {}'.format(args))
{print(key,'<--->',value,'\n') for key,value in kw.items()}
return super(Util,self).__init__() args =(1,2,3)
kw = dict(name='frank',city='changsha')
util = Util(*args,**kw)
print(type(util))
输出结果:
------UtilMetaclass---__new__ ---start----
meta_cls: <class '__main__.UtilMetaclass'>
cls: Util
bases:(<class 'object'>,)
attr_dict: {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d542b2ea0>, '__new__': <function Util.__new__ at 0x7f4d542b2488>} -----UtilMetaclass----__init__ ----start---
self: <class '__main__.Util'>
args: ('Util', (<class 'object'>,), {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d542b2ea0>, '__new__': <function Util.__new__ at 0x7f4d542b2488>}) -----Util----__new__ ----start---
cls: <class '__main__.Util'>
args: (1, 2, 3)
kw: name <---> frank kw: city <---> changsha -----Util----__init__ ----start---
self: <__main__.Util object at 0x7f4d540f4a20>
args: (1, 2, 3)
name <---> frank city <---> changsha <class '__main__.Util'>

添加上这个 return 语句 其实发现也没什么变化,这就从侧面说明了 new 会调用 init ,而 init 会到继承链(我取的名字)上去找。。。添加上 return 不过是再次调用了 type 的 构造方法罢了,其实没有必要,一般 init 方法中是不需要返回值的这点跟java一样。。。

class UtilMetaclass(type):
def __new__(meta_cls,cls,bases,attr_dict):
print('------UtilMetaclass---__new__ ---start----')
print('meta_cls: {}'.format(meta_cls))
print('cls: {}'.format(cls))
print('bases:{}'.format(bases))
print('attr_dict: {}\n'.format(attr_dict))
return type.__new__(meta_cls,cls,bases,attr_dict) def __init__(self,*args,**kw):
print('-----UtilMetaclass----__init__ ----start---')
print('self: {}'.format(self))
print('args: {}\n'.format(args))
{print('kw:',key,'<--->',value,'\n') for key,value in kw.items()}
return super(UtilMetaclass,self).__init__(*args,**kw) class Util(object,metaclass=UtilMetaclass):
def __new__(cls,*args,**kw):
print('-----Util----__new__ ----start---')
print('cls: {}'.format(cls))
print('args: {}'.format(args))
{print('kw:',key,'<--->',value,'\n') for key,value in kw.items()}
return object.__new__(cls) def __init__(self,*args,**kw):
print('-----Util----__init__ ----start---')
print('self: {}'.format(self))
print('args: {}'.format(args))
{print(key,'<--->',value,'\n') for key,value in kw.items()}
return super(Util,self).__init__() args =(1,2,3)
kw = dict(name='frank',city='changsha')
util = Util(*args,**kw)
print(type(util)) 输出结果:
------UtilMetaclass---__new__ ---start----
meta_cls: <class '__main__.UtilMetaclass'>
cls: Util
bases:(<class 'object'>,)
attr_dict: {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d542b2d90>, '__new__': <function Util.__new__ at 0x7f4d542b29d8>} -----UtilMetaclass----__init__ ----start---
self: <class '__main__.Util'>
args: ('Util', (<class 'object'>,), {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d542b2d90>, '__new__': <function Util.__new__ at 0x7f4d542b29d8>}) -----Util----__new__ ----start---
cls: <class '__main__.Util'>
args: (1, 2, 3)
kw: name <---> frank kw: city <---> changsha -----Util----__init__ ----start---
self: <__main__.Util object at 0x7f4d540f4518>
args: (1, 2, 3)
name <---> frank city <---> changsha <class '__main__.Util'>
class SingletonMetaclass(type):
def __new__(cls,*args,**kw):
print('new in SingletonMetaclass start...')
return super(SingletonMetaclass,cls).__new__(cls,*args,**kw)
def __init__(self,*args,**kw):
print('init in SingletonMetaclass start...') def __call__(cls,*args,**kw):
print('call in SingletonMetaclass start...')
if not hasattr(cls,'obj'):
cls.obj = cls.__new__(cls,*args,**kw)
cls.__init__(cls.obj,*args,**kw)
return cls.obj class Singleton(object,metaclass=SingletonMetaclass):
def __new__(cls,*args,**kw):
print('new in Singleton start...')
return super(Singleton,cls).__new__(cls,*args,**kw) def __init__(self,*args,**kw):
print('init in Singleton start...') def __call__(self,*args,**kw):
print('call in Singleton start...') Singleton s1 = Singleton()
s2 = Singleton() s1 == s2

python 创建实例--待完善的更多相关文章

  1. python 创建实例对象

    实例化类其他编程语言中一般用关键字 new,但是在 Python 中并没有这个关键字,类的实例化类似函数调用方式. 以下使用类的名称 Employee 来实例化,并通过 __init__ 方法接收参数 ...

  2. openstack私有云布署实践【19 通过python客户端 创建实例VM指定IP地址】

    还有一种创建方式 是使用py开发工具,调用openstackclient的方法进行创建实例 ,好处就是可随意指定我们要的虚拟机IP地址,需求的场景就是,某天我们需要主动分配一个比较熟知的IP用作某个服 ...

  3. python之定义类创建实例

    https://www.cnblogs.com/evablogs/p/6688938.html 类的定义 在Python中,类通过class关键字定义,类名以大写字母开头 1 2 >>&g ...

  4. python创建MySQL多实例-1

    python创建MySQL多实例-1 前言 什么是多实例 多实例就是允许在同一台机器上创建另外一套不同配置文件的数据库,他们之间是相互独立的,主要有以下特点, 1> 不能同时使用一个端口 2&g ...

  5. python基础教程:定义类创建实例

    类的定义 在Python中,类通过class关键字定义,类名以大写字母开头 >>>class Person(object): #所有的类都是从object类继承 pass #pass ...

  6. python基础——实例属性和类属性

    python基础——实例属性和类属性 由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(objec ...

  7. 1.面向过程编程 2.面向对象编程 3.类和对象 4.python 创建类和对象 如何使用对象 5.属性的查找顺序 6.初始化函数 7.绑定方法 与非绑定方法

    1.面向过程编程 面向过程:一种编程思想在编写代码时 要时刻想着过程这个两个字过程指的是什么? 解决问题的步骤 流程,即第一步干什么 第二步干什么,其目的是将一个复杂的问题,拆分为若干的小的问题,按照 ...

  8. Python 创建和使用类

    python创建和使用类的方法如下 # class Dog(): # def __init__(self,name,age): # self.name=name # self.age=age # # ...

  9. 使用python创建mxnet操作符(网络层)

    对cuda了解不多,所以使用python创建新的操作层是个不错的选择,当然这个性能不如cuda编写的代码. 在MXNET源码的example/numpy-ops/下有官方提供的使用python编写新操 ...

随机推荐

  1. 安裝CentOS7后修復win7引导

    想尝试双系统的心情想必大家都能理解,但是安装了双系统之后的收尾工作也是必不可少的,由于对Linux并不算很熟悉,所以在这方面花了不少时间,这里将CentOS7下修復windows7引导的解决方案记录下 ...

  2. Entity Framwork学习笔记

    一.First Demo

  3. Oracle 测试环境 数据库安装过程

    1. 搭建windows服务器或者虚拟机, 需要处理的地方: 1) 关闭防火墙(测试环境使用) 2)  更新必要的安全补丁(不连入网络时进行处理) 3)  打开远程访问. 4) 修改电源模式,建议使用 ...

  4. msyql sql语句收集

    在不断的学习中,发现了一些新的slq语句,总结于此. 一.复制数据表的sql 1)create table tableName  as  select  * from   tableName2     ...

  5. angular2+中数据变更子组件页面未更新

    引入监测 import {ChangeDetectorRef} from '@angular/core'; constructor( private changeDetectorRef:ChangeD ...

  6. 关于python性能相关测试cProfile库

    http://blog.csdn.net/gzlaiyonghao/article/details/1483728 收藏一个大神对这个问题的介绍. 我就不多做污染了.另外还有两个 增强库可以针对cPr ...

  7. centos网络yum源的安装

    CentOS使用EPEL YUM源EPEL (Extra Packages for Enterprise Linux)是基于Fedora的一个项目,为“红帽系”的操作系统提供额外的软件包,适用于RHE ...

  8. TMainMenu - 隐藏与显示菜单

    //隐藏与显示菜单 Self.Menu := nil; {隐藏菜单} Self.Menu := MainMenu1; {显示菜单}

  9. BZOJ3590 SNOI2013Quare(状压dp)

    可能作为最优解的边双都可以这样生成:初始时边双内只有一个点,每次选取边双内部两点(可以相同)和一个当前不在边双内的点集,以该两点为起止点找一条链(当然如果两点相同就是个环)将点集串起来,加入边双.状压 ...

  10. MT【66]寻找对称中心

    设函数$f(x)=2x-cosx,{a_n}$是公差为$\frac{\pi}{8}$的等差数列,$f(a_1)+f(a_2)+f(a_3)+f(a_4)+f(a_5)=5\pi$,则 $[f(a_3) ...