1.旧式类

在讲新式类之前,先看看旧式类是怎么用的。

class OldClass:passOldClass()

上面就是旧式类的写法,默认继承type类。

2.新式类

python2中,如果定义一个新式类

class NewClass(object):pass

而在python3中,所有的类,均默认继承object,所以括号里也可以不显示指定object。

3.__new__方法与__init__方法

如果我们再IDE里面输入__new__字样,IDE会自动给我们补全方法如下:

class NewClass(object):def __new__(cls, *args, **kwargs):super().__new__()

而如果是输入__init__字样,IDE会自动给我们补全方法如下:

class NewClass(object):def __new__(cls, *args, **kwargs):super().__new__()def __init__(self):pass

先说结论:

__new__的第一个参数是cls(当然你也可以叫别的名字,但是cls是约定俗成),是用来创建类的实例的(constructor)。
__init__的第一个参数是self,是用来初始化实例的(initializer),这个实例的名字就是self。

class NewClass(object):def __new__(cls, *args, **kwargs):print("this is __new__ method!")instance = super(NewClass, cls).__new__(cls)return instancedef __init__(self):print("this is __init__ method!")passNewClass()

代码的输出为:

this is __new__ method!
this is __init__ method!

从上面代码的执行结果可以看出,在创建NewClass类实例并初始化的过程中,__new__方法与__init__方法都被调用了。先是通过__new__方法创建了一个类实例,然后再通过__init__方法初始化。

如果我们把__new__方法中的return一行去掉,不返回任何对象,则__init__方法不会被调用!

class NewClass(object):def __new__(cls, *args, **kwargs):print("this is __new__ method!")instance = super(NewClass, cls).__new__(cls)def __init__(self):print("this is __init__ method!")print("self is: ", self)passNewClass()

代码输出结果为

this is __new__ method!

如果__new__方法返回一个已经存在的对象,不管该对象是什么类型,__init__方法也不会被调用。

s = "abc"class NewClass(object):def __new__(cls, *args, **kwargs):print("this is __new__ method!")instance = super(NewClass, cls).__new__(cls)return sdef __init__(self):print("this is __init__ method!")print("self is: ", self)passNewClass()

代码输出结果为

this is __new__ method!

4.__init__必须返回None

在__init__方法中,返回类型必须为None。看如下代码

class NewClass(object):def __new__(cls, *args, **kwargs):instance = super(NewClass, cls).__new__(cls)return instancedef __init__(self):return "abc"NewClass()

执行结果如下:

TypeError: __init__() should return None, not 'str'

5.__new__方法的作用

按照python官方文档的解释,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。

class PositiveNum(int):def __new__(cls, value):return super().__new__(cls, abs(value))num = PositiveNum(-10)
print(num)

上面的例子,就是通过重写new方法,得到了一个正整数的类。

6.__new__实现单例模式

我们可以通过new方法,来实现一个单例模式。

class Singleton(object):_instance = Nonedef __new__(cls, *args, **kwargs):if cls._instance is None:cls._instance = super().__new__(cls, *args, **kwargs)return cls._instancedef test_singleton():s1 = Singleton()s2 = Singleton()print(s1)print(s2)test_singleton()
<__main__.Singleton object at 0x116e65a50>
<__main__.Singleton object at 0x116e65a50>

通过上面的例子可以看出来,s1与s2的内存地址一样,指向的是同一个实例对象。

7.工厂模式

class Bird(Animal):def __init__(self):passdef print_name(self):print("my name is Bird!")class Cat(Animal):def __init__(self):passdef print_name(self):print("my name is Cat!")class Factory(object):animals = {"bird": Bird, "cat": Cat}def __new__(cls, name):if name in cls.animals.keys():return cls.animals[name]()else:return Animaldef test_factory():bird = Factory("bird")cat = Factory("cat")bird.print_name()cat.print_name()test_factory()
my name is Bird!
my name is Cat!

python新式类中的__new__方法与__init__方法相关推荐

  1. python类中方法的执行顺序-python – 新式类中的方法解析顺序(MRO)?

    在Python in a Nutshell(第2版)一书中有一个使用的例子 旧样式类,用于演示如何以经典分辨率顺序解析方法 它与新订单有何不同. 我通过重写新样式的示例尝试了相同的示例,但结果与使用旧 ...

  2. python隐藏部分代码_python隐藏类中属性的3种实现方法

    方法一: 效果图一: 代码一: # 定义一个矩形的类 class Rectangle: # 定义初始化方法 def __init__(self,width,height): self.hidden_w ...

  3. python新式类和经典类区别_Python中新式类和经典类的区别,钻石继承

    1)首先,写法不一样: class A: pass class B(object): 2)在多继承中,新式类采用广度优先搜索,而旧式类是采用深度优先搜索. 3)新式类更符合OOP编程思想,统一了pyt ...

  4. python新式类c3算法_Python 新式类继承关系的 C3 算法(Python 2.3 的方法解析顺序,MRO)...

    Python 新式类继承关系的 C3 算法(Python 2.3 的方法解析顺序,MRO) 翻译:刘硕 摘要:本文档面向于想要了解Python 2.3版本中 C3 方法解析顺序的 Python程序开发 ...

  5. Python类中的私有属性和私有方法

    Python类中的私有属性和私有方法 Python是面向对象的语言,在Python里一切皆对象,所以大部分情况下,我们都是通过类的方式来编程. 但是Python中的属性和方法在类的外部默认是可以访问的 ...

  6. python新式类和经典类的区别

    python新式类和经典类的区别 1,新式类和经典类的区别: 广度优先和深度优先,这主要是在多类继承的时候会使用到,如下多类继承的D类对比: 经典类在加载的时候采用的是深度优先算法,二新式类采用的是广 ...

  7. python定义类()中写object和不写的区别

    python定义类()中写object和不写的区别 这里需要说明一下: python3中,类定义默认继承object,所以写不写没有区别 但在python2中,并不是这样 所以此内容是针对python ...

  8. python init方法做了什么_Python类方法、__new__方法和__init__方法分别是什么

    Python类方法.__new__方法和__init__方法分别是什么 发布时间:2020-09-03 15:24:06 来源:亿速云 阅读:104 作者:小新 这篇文章主要介绍Python类方法._ ...

  9. python新式类和旧式类的区别_浅谈python新式类和旧式类区别

    python的新式类是2.2版本引进来的,我们可以将之前的类叫做经典类或者旧式类. 为什么要在2.2中引进new style class呢?官方给的解释是: 为了统一类(class)和类型(type) ...

  10. python新式类好还是经典类_python新式类和经典类的区别?

    python新式类和经典类的区别? 1)首先,写法不一样: class A: pass class B(object): pass 2)在多继承中,新式类采用广度优先搜索,而旧式类是采用深度优先搜索. ...

最新文章

  1. stm32qspi内存映射_stm32 QSPI内存映射模式
  2. 5.0:Spring-bean的加载
  3. 在Java中VO , PO , BO , QO, DAO ,POJO是什么意思
  4. R语言switch语句报错Error: duplicate ‘switch‘ defaults
  5. 中国恒大:正接触独立第三方投资者
  6. 【重点】剑指offer——面试题62:序列化二叉树
  7. mysql buffer size_mysql read_buffer_size 设置多少合适
  8. Visual Studio 2008 Designer.cs不能更新/自动添加控件声明的解决办法
  9. 网页设计软件html图标,网页设计Photoshop(PS)CSS切图必用工具
  10. 【SpringBoot系列】最详细demo--集成JWT实现接口权限认证
  11. python堆叠柱状图加数字_Python 堆叠柱状图绘制方法
  12. 需要一个红警2的易语言源码
  13. Vue组件化开发--脚手架的安装使用、目录结构说明
  14. 双基管理 运营_浅谈银行“双基”管理的重要性
  15. java (零钱通)
  16. 理解计算机3D图形学中的坐标系变换
  17. 文献阅读-区块链发展现状与展望
  18. Java字符串面试题
  19. 海贼王之伟大航路——状压记忆化搜索
  20. Java中的Base64详解

热门文章

  1. ListenalbeFuture的使用总结
  2. BZOJ3457 : Ring
  3. 最适合数据分析师的数据库为什么不是MySQL?
  4. 【python】编程语言入门经典100例--23
  5. SSDP:DDoS***的“新宠”
  6. linux下载百度网盘文件
  7. Linux内核等待队列wait_queue学习
  8. .通过JAVA-Webservices向其它平台提供Hbase服务
  9. 理想的工作永远不存在
  10. 服务器端登陆机制的 实现模块