今天好好琢磨一下 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. Vue.directive注册指令

    指令定义函数提供了几个钩子函数(可选): vue指令的生命周期 bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作. inserted: 被绑定 ...

  2. React state状态

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  3. pandas文件写入读取操作

    #encoding:utf8 import pandas as pd import numpy as np from pylab import * df=pd.read_csv("./pat ...

  4. tomcat启动失败问题总结

    一.端口占用 linux下启动tomcat的时候,如果服务启动不成功,可以到查看logs文件夹下的catalina.out  日志文件,cat我的日志文件可得到如下的错误信息:(Caused by:  ...

  5. loadrunner 基础-学习笔记一

    由于公司要使用loadrunner暂停学习jmeter 1 loadrunner组件: virtual user generator:录制最终用户业务流程并创建自动化性能测试脚本,vuser脚本 co ...

  6. Centos 7最小化安装后配置

    关闭SELINUX vi /etc/sysconfig/selinux SELINUX=disabled :wq 配置网卡(最小化安装后ifconfig无法使用),该配置的前提是采用 NAT模式 vi ...

  7. Python——多进程

    进程的实例 # -*- coding:UTF-8 -*- import os import time from multiprocessing import Process #进程 def func( ...

  8. 关于super的理解,三篇文章支撑起来的

    1.有向图的拓扑排序https://blog.csdn.net/wp1603710463/article/details/50900892 2. Python中MRO算法 http://mp.weix ...

  9. 腾讯云 Ubuntu16.04 搭建Git 服务

    一.安装Git服务器所需软件 1.安装git-core, openssh-server, openssh-client三个软件.git-core是git的核心软件: openssh-server.op ...

  10. poj2115-C Looooops -线性同余方程

    线性同余方程的模板题.和青蛙的约会一样. #include <cstdio> #include <cstring> #define LL long long using nam ...