今天好好琢磨一下 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. Java使用HTTPClient3.0.1开发的公众平台消息模板的推送功能

    package com.company.product.manager.busniess.impl; import java.io.IOException;import java.nio.charse ...

  2. mysql distinct 去重

    在使用MySQL时,有时需要查询出某个字段不重复的记录,这时可以使用mysql提供的distinct这个关键字来过滤重复的记录,但是实际中我们往往用distinct来返回不重复字段的条数(count( ...

  3. python学习笔记三——控制语句

    2.5 运算符与表达式 2.5.1 算术运算符和算术表达式 算术运算符包括四则运算符.求模运算符和求幂运算符. 算术运算符 加减乘除:+ - * / 表达式:x+y   x-y   x*y  x/y ...

  4. checkStyle 错误普及

    1Type is missing a javadoc commentClass  缺少类型说明 2“{” should be on the previous line“{” 应该位于前一行.解决方法: ...

  5. jenkins--java配置

    进入jenkins然后-->系统配置-->Global Tool Configuration

  6. [IOI2018]会议——分治+线段树

    题目链接: [IOI2018]meetings 题目大意:有$n$座山峰,每座山峰有一个高度,有$q$次询问,每次需要确定一个开会山峰使$[l,r]$所有山峰上的人都前往开会山峰,一个山峰的人去开会的 ...

  7. 【Linux】Centos7 解压zip文件

    如果输入unzip无反应那么请安装相应软件包 yum install -y unzip 语法 unzip [参数] [文件] 参数 -c:将解压缩的结果显示到屏幕上,并对字符做适当的转换: -f:更新 ...

  8. hdu 5126 stars (四维偏序,离线,CDQ套CDQ套树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5126 思路:支持离线,那么我们可以用两次CDQ分治使四维降为二维,降成二维后排个序用树状数组维护下就好 ...

  9. MT【27】对数方程组求范围

    解答:3 评论:此类题目通性通法为换元后化归为线性规划问题.当然不等式凑配也是常见技巧,只是容易范围扩大或者缩小.

  10. android第二课:运行你的应用

    如果你按照前面课程创建了 Android 项目,它包含了可以立即运行的 "Hello World"源代码文件. 由两该条件来决定如何运行你的应用:你是否拥有运行着 Android ...