__new__构造函数的常用做法?

gre*_*man 5 python constructor

我知道(?)关于__new__Python中构造函数背后的理论,但我要问的是常见的做法 - 这个构造函数真正用于什么目的(!)?

我读过有关初始化不可变对象(逻辑从移动__init____new__),别的什么吗?工厂模式?

请再次注意区别:

  • __new__可以使用什么任务- 我不感兴趣
  • 对于哪些任务__new__ 使用-我:-)

我不用Python写任何东西,我的知识来自阅读,而不是来自经验.

你可以在哪里真正回答这个问题:构造函数的常见做法?

Ste*_*ini 3

要点__new__是创建一个空对象实例,__init__然后进行初始化。重新实现__new__您可以完全控制您创建的实例,但您无法实际使用该__init__方法进行任何进一步的处理。我可以为您提供两种有用的情况:自动创建方法以及使用智能构造函数从类的磁盘进行反序列化。这些并不是解决这两个问题的唯一方法。元类是另一种更灵活的方式,但与任何工具一样,您可能希望获得不同程度的复杂性。

自动创建方法

假设您想要一个具有给定属性集的类。您可以使用如下代码控制这些属性的初始化方式

class Foo(object):                                                                                                                                    
    properties = []                                                                                                                                   
    def __new__(cls, *args):                                                                                                                          
        instance = object.__new__(cls, *args)                                                                                                         
        for p in cls.properties:                                                                                                                      
            setattr(instance, p, 0)                                                                                                                   
        return instance                                                                                                                               

class MyFoo(Foo):                                                                                                                                     
    properties = ['bar', 'baz']                                                                                                                       

    def __init__(self):                                                                                                                               
        pass                                                                                                                                          



f=MyFoo()                                                                                                                                             
print dir(f)   
Run Code Online (Sandbox Code Playgroud)

你想要的属性直接初始化为零。您可以使用很多聪明的技巧,例如动态地执行属性列表。所有实例化的对象都将具有这些方法。这种模式的一个更复杂的情况出现在Django Models中,您可以在其中声明字段并免费获得许多自动的东西,这要感谢__new__老大哥元类。

从磁盘反序列化

假设您有一个具有给定构造函数的类,该构造函数从对象(例如进程)填充该类的字段:

class ProcessWrapper(object):                                                                                                                         
    def __init__(self, process):                                                                                                                      
        self._process_pid = process.pid()                                                                                                             

    def processPid(self):                                                                                                                             
        return self._process_pid           
Run Code Online (Sandbox Code Playgroud)

如果您现在将此信息序列化到磁盘并想要恢复它,则无法通过构造函数进行初始化。所以你写了一个像这样的反序列化函数,有效地绕过了__init__你无法运行的方法。

def deserializeProcessWrapperFromFile(filename):                                                                                                      
    # Get process pid from file                                                                                                                       
    process = ProcessWrapper.__new__()                                                                                                                
    process._process_pid = process_pid                                                                                                                
    return process         
Run Code Online (Sandbox Code Playgroud)