为什么在类中定义“__new__”和“__init__” [英] why defined '__new__' and '__init__' all in a class
问题描述
我认为你可以在类中定义' __ init __
'或' __ new __
在django.utils.datastructures.py。
我的代码:
class a(object):
def __init __(self):
print'aaa'
def __new __(self):
print'sss'
$ b ba()#print'sss'
class b:
def __init __(self):
print'aaa'
def __new __(self):
print'sss'
b()#print'aaa'
datastructures.py:
class SortedDict(dict):
一个字典,
def __new __(cls,* args,** kwargs):
instance = super(SortedDict,cls).__ new __(cls,* args, ** kwargs)
instance.keyOrder = []
返回实例
def __init __(self,data = None):
如果数据为None:
data = {}
super(SortedDict,self).__ init __(data)
if isinstance(data,dict):
self.keyOrder = data.keys()
else :
self.keyOrder = []
键,数据中的值:
如果键不在self.keyOrder中:
self.keyOrder.append(key)
在什么情况下会调用 SortedDict .__ init __
/ p>
感谢
您可以定义 __ 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 __
中,这个想法值得记住。
i think you can defined either '__init__
' or '__new__
' in a class,but why all defined in django.utils.datastructures.py.
my code:
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)
and what circumstances the SortedDict.__init__
will be call.
thanks
You can define either or both of __new__
and __init__
.
__new__
must return an object -- which can be a new one (typically that task is delegated to type.__new__
), an existing one (to implement singletons, "recycle" instances from a pool, and so on), or even one that's not an instance of the class. If __new__
returns an instance of the class (new or existing), __init__
then gets called on it; if __new__
returns an object that's not an instance of the class, then __init__
is not called.
__init__
is passed a class instance as its first item (in the same state __new__
returned it, i.e., typically "empty") and must alter it as needed to make it ready for use (most often by adding attributes).
In general it's best to use __init__
for all it can do -- and __new__
, if something is left that __init__
can't do, for that "extra something".
So you'll typically define both if there's something useful you can do in __init__
, but not everything you want to happen when the class gets instantiated.
For example, consider a class that subclasses int
but also has a foo
slot -- and you want it to be instantiated with an initializer for the int
and one for the .foo
. As int
is immutable, that part has to happen in __new__
, so pedantically one could code:
>>> 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
>>>
In practice, for a case this simple, nobody would mind if you lost the __init__
and just moved the self.foo = foo
to __new__
. But if initialization is rich and complex enough to be best placed in __init__
, this idea is worth keeping in mind.
这篇关于为什么在类中定义“__new__”和“__init__”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!