__new__函数的作用

2021年4月24日 / 108次阅读 / Last Modified 2021年5月17日
面向对象

__new__是类定义中的一个magic method,而且还是一个class method,不需要使用@classmethod装饰器

__new__函数从代码执行流程上看,如果被定义,在创建类的对象实例时,__init__函数将不会默认被执行。这里有个概念:__init__只是对象的初始化,比如初始化一些成员变量等;初始化之前,首先要创建对象,创建的动作一般python解释器自己就做了;如果定义了__new__函数,它应该要承担起创建并初始化对象的工作。

自己在使用python过程中,还没有遇到过特别需要使用__new__的场景,下面仅是一个非常简单的示例代码:

class aa():

    def __new__(cls):
        print('__new__')

    def __init__(self):
        print('__init__')


a1 = aa()
print(a1)

执行效果是这样的:

D:\py>python t1.py
__new__
None

在创建对象时,__new__被调用,默认返回了None对象,__init__函数被忽略了!可以把代码稍微修改一下,让__new__返回当前类的对象:

class aa():

    def __new__(cls):
        print('__new__')
        return object.__new__(cls)

    def __init__(self):
        print('__init__')


a1 = aa()
print(a1)

执行效果如下:

D:\py>python t1.py
__new__
__init__
<__main__.aa object at 0x0000019FE7018278>

在stackoverflow上看到一段文字,对使用__new__的场景有一点介绍:

New-style classes introduced a new class method __new__() that lets the class author customize how new class instances are created. By overriding __new__() a class author can implement patterns like the Singleton Pattern, return a previously created instance (e.g., from a free list), or to return an instance of a different class (e.g., a subclass). However, the use of __new__ has other important applications. For example, in the pickle module, __new__ is used to create instances when unserializing objects. In this case, instances are created, but the __init__ method is not invoked.

Another use of __new__ is to help with the subclassing of immutable types. By the nature of their immutability, these kinds of objects can not be initialized through a standard __init__() method. Instead, any kind of special initialization must be performed as the object is created; for instance, if the class wanted to modify the value being stored in the immutable object, the __new__ method can do this by passing the modified value to the base class __new__ method.

关于这个话题,以后遇到特别的需求时,再来总结。学习过程中发现一个好网站,The History of Python, http://python-history.blogspot.com/,是Guido自己写的Blog,没事儿的时候,值得阅读!

Singleton Design Pattern

The singleton pattern is one of the simplest design patterns. Sometimes we need to have only one instance of our class for example a single DB connection shared by multiple objects as creating a separate DB connection for every object may be costly. Similarly, there can be a single configuration manager or error manager in an application that handles all problems instead of creating multiple managers.

class xyz():

    meOnly = None

    def __new__(cls):
        if cls.meOnly:
            return cls.meOnly
        else:
            cls.meOnly = object.__new__(cls)
            cls.meOnly.__init__()
            return cls.meOnly

    def __init__(self):
        self.x = 1
        self.y = 2
        self.z = 3

x = xyz()
print(id(x))
y = xyz()
print(id(y))
print(x.x)
print(y.y)
if x is y:
    print('x is y')

利用class variable和__new__实现singleton pattern。以上代码运行效果如下:

$ python3 singleton.py
35731976
35731976
1
2
x is y

-- EOF --

本文链接:https://www.pynote.net/archives/3609

留言区

您的电子邮箱地址不会被公开。 必填项已用*标注


前一篇:
后一篇:

More


©Copyright 麦新杰 Since 2019 Python笔记

go to top