我认为你可以在一个类中定义' __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'
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
什么情况下SortedDict.__init__会被召唤.
谢谢
Ale*_*lli 20
您可以定义一个或两个__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
>>>
Run Code Online (Sandbox Code Playgroud)
在实践中,对于一个简单的案例,没有人会介意你失去了__init__,只是移动self.foo = foo到了__new__.但是如果初始化很丰富且复杂到最好__init__,那么这个想法值得记住.
__new__和__init__做完全不同的事情.该方法__init__启动一个类的新实例---它是一个构造函数.__new__是一个更微妙的东西---它可以改变参数,事实上,它可以改变发起对象的类.例如,以下代码:
class Meters(object):
def __new__(cls, value):
return int(value / 3.28083)
Run Code Online (Sandbox Code Playgroud)
如果你打电话,Meters(6)你实际上不会创建一个实例Meters,而是一个实例int.你可能想知道为什么这是有用的; 它对于元类来说实际上是至关重要的,这是一个公认的模糊(但功能强大)的功能.
您会注意到,在Python 2.x中,只有继承自的类object可以利用__new__,如上面的代码所示.
__new__在django中显示的使用似乎是试图在SortedDict对象上保持理智的方法解析顺序.但我承认,通常很难说为什么__new__有必要.标准Python风格表明除非必要,否则不会使用它(一如既往,更好的类设计是您首先使用的工具).