小编典典

为什么在一个类中都定义了“ __new__”和“ __init__”

python

我认为您可以在类中定义“ __init__”或“
__new__”,但是为什么都在django.utils.datastructures.py中定义。

我的代码:

class a(object):
    def __init__(self):
        print  'aaa'
    def __new__(self):
        print 'sss'

a()#print 'sss'

class b:
    def __init__(self):
        print  'aaa'
    def __new__(self):
        print 'sss'
b()#print 'aaa'

datastructures.py:

class SortedDict(dict):
    """
    A dictionary that keeps its keys in the order in which they're inserted.
    """
    def __new__(cls, *args, **kwargs):
        instance = super(SortedDict, cls).__new__(cls, *args, **kwargs)
        instance.keyOrder = []
        return instance

    def __init__(self, data=None):
        if data is None:
            data = {}
        super(SortedDict, self).__init__(data)
        if isinstance(data, dict):
            self.keyOrder = data.keys()
        else:
            self.keyOrder = []
            for key, value in data:
                if key not in self.keyOrder:
                    self.keyOrder.append(key)

以及SortedDict.__init__将在什么情况下致电。

谢谢


阅读 245

收藏
2021-01-20

共1个答案

小编典典

您可以定义一个或两个的__new____init__

__new__必须返回一个对象-
可以是一个新对象(通常将任务委派给该对象type.__new__),一个现有对象(以实现单例,从池中“回收”实例,依此类推),甚至可以 不是
一个实例。班级。如果__new__返回该类的实例(新的或现有的),__init__则对其进行调用;如果__new__返回一个对象,这
不是 一个类的实例,则__init__ 叫。

__init__将类实例作为其第一项传递给它(以相同的状态__new__返回,即通常为“空”),并且必须根据需要对其进行更改以使其可以使用(通常是通过添加属性)。

总的来说,最好将其__init__用于所有可以做的事情-
并且__new__,如果遗留了一些__init__不能做的事情,则应使用该“多余的东西”。

因此,您通常会定义两者是否可以在其中做些有用的事情__init__,而不是定义实例化类时想要发生的一切。

例如,考虑一个既有子类int又具有foo插槽的类,并且您希望使用的初始化器int和的初始化器实例化该类.foo。由于这int是不可变的,因此该部分必须在中发生__new__,因此,一个人可以编写以下代码:

>>> class x(int):
...   def __new__(cls, i, foo):
...     self = int.__new__(cls, i)
...     return self
...   def __init__(self, i, foo):
...     self.foo = foo
...   __slots__ = 'foo',
... 
>>> a = x(23, 'bah')
>>> print a
23
>>> print a.foo
bah
>>>

在实践中,这种简单的情况下,没有人会如果你失去了头脑__init__,只是移动self.foo = foo__new__。但是,如果初始化足够丰富且复杂,以至于无法最佳使用__init__,则此想法值得牢记。

2021-01-20