今天好好琢磨一下 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. back to top 回到顶部按钮 css+js

    效果 html <p id="back-to-top"><a href="#top"><span></span> ...

  2. 【转帖】Systemd 入门教程:命令篇

    Systemd 入门教程:命令篇  Copy From http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html 感觉 ...

  3. OA与BPM的区别

      BPM OA 软件架构 JAVA..NET.基于SOA架构 JAVA..NET.PHP.Domino 驱动模式 流程驱动 文档驱动 交互 人与人,人与系统,系统与系统 人与人 软件功能       ...

  4. 14Junit、反射、注解

    14Junit.反射.注解 14.1.1 Junit的概述      一般IDE都内置了junit,若需要自行下载jar包,可以访问官网,官网地址如下:http://www.junit.org 1. ...

  5. BZOJ1419Red is good——概率DP

    题目描述 桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付 出1美元.可以随时停止翻牌,在最优策略下平均能得到多少钱. 输入 一行输入两个数R,B ...

  6. QAU 18校赛 J题 天平(01背包 判断能否装满)

    问题 J: 天平 时间限制: 1 Sec  内存限制: 128 MB提交: 36  解决: 9[提交][状态][讨论版][命题人:admin] 题目描述 天平的右端放着一件重量为w的物品.现在有n个重 ...

  7. php动态获取常量

    class A1{ const V1='100'; const V2='200'; const V3='Hello world'; } $v1 = 'V3'; $a1 = constant('A1:: ...

  8. 在Java Web程序中使用监听器可以通过以下两种方法

    之前学习了很多涉及servlet的内容,本小结我们说一下监听器,说起监听器,编过桌面程序和手机App的都不陌生,常见的套路都是拖一个控件,然后给它绑定一个监听器,即可以对该对象的事件进行监听以便发生响 ...

  9. 【转】Linux 移动或重命名文件/目录-mv 的10个实用例子

    熟悉了 复制命令,下一个相关的命令就是 mv 命令.当你想要将文件从一个位置移动到另一个地方并且不想复制它,那么mv 命令是完成这个任务的首选. 初识 mv 命令 mv 命令是一个与cp类似的命令,但 ...

  10. rsync同步官方zabbix仓库搭建本地yum源

    1.同步资源 # rsync -vrt rsync://repo.zabbix.com/mirror/zabbix/3.4/rhel/7/x86_64/ /home/mirrors/zabbix/3. ...