我认为你可以在一个类中定义'__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'
在数据结构.py公司名称:
^{pr2}$以及在什么情况下SortedDict.__init__
将被调用。在
谢谢
我唯一的猜测是,在这种情况下,他们(这个类的作者)希望keyOrder列表在调用
SortedDict.__init__
之前就存在于类中。在注意SortedDict在其}等来开始添加项。}的问题,因为我的本能本能反应是在调用}。在
__init__
中调用super()
,这通常会转到dict.__init__
,这可能会调用{SortedDict.__setitem__
期望.keyOrder
属性存在,问题就在这里(因为.keyOrder
通常是在调用super()
之后才创建的)可能这只是子类化{super()
之前初始化{__new__
中的代码也可用于允许SortedDict在菱形继承结构中进行子类化,在这种结构中,在调用第一个__setitem__
之前,SortedDict.__init__
不被调用。Django在支持从2.3以上的各种python版本时必须面对各种各样的问题;在某些版本中,这些代码可能是完全不必要的,而在其他版本中则是需要的。在定义}(在元类的存在中,这甚至可能不是正确的事情)。在
__new__
和__init__
有一个共同的用途:访问可能被其实例版本掩盖的类属性,而不必执行type(self)
或{例如:
最后,
__new__
实际上可以返回一个包装器的实例或一个完全不同于您所想实例化的类的实例。这用于提供类似元类的特性,而不需要真正的元类。在__new__
和{__init__
启动一个类的新实例——它是一个构造函数。__new__
是一个更微妙的东西——它可以改变参数,事实上,改变启动对象的类。例如,以下代码:如果调用
Meters(6)
,实际上不会创建Meters
的实例,而是int
的实例。您可能会想知道为什么这是有用的;它实际上对元类至关重要,元类是一个公认的晦涩(但功能强大)的特性。在您将注意到,在python2.x中,只有继承自
object
的类才能利用__new__
,如上面的代码所示。在您在django中展示的使用
__new__
似乎是为了保持SortedDict
对象的合理方法解析顺序。不过,我承认,很难说为什么__new__
是必要的。标准的Python风格建议除非有必要,否则不要使用它(一如既往,最好的类设计是您首先使用的工具)。在您可以定义
__new__
和__init__
中的一个或两个。在__new__
必须返回一个对象——它可以是一个新的对象(通常该任务被委派给type.__new__
)、一个现有的对象(实现singleton,“回收”池中的实例,等等),甚至是一个而不是类的实例。如果__new__
返回类的一个实例(新的或现有的),__init__
然后被调用;如果__new__
返回的对象不是类的实例,那么__init__
将被调用而不是。在向
__init__
传递一个类实例作为它的第一个项(在相同的状态下,__new__
返回了它,即通常为“空”),并且必须根据需要修改它以使其准备好使用(通常通过添加属性)。在一般来说,最好使用}不能做的事情,那么就用这个“额外的东西”。在
__init__
来完成所有它能做的事情——并且__new__
,如果留下了{因此,如果在
__init__
中可以做一些有用的事情,那么通常会定义这两者,但不是类实例化时希望发生的所有事情。在例如,考虑一个类的子类}的初始值设定项实例化。由于
int
,但也有一个foo
槽,并且您希望它用int
的初始值设定项和{int
是不可变的,因此该部分必须发生在__new__
中,因此可以用迂腐的方式编写:实际上,对于这样一个简单的例子,没有人会介意您是否丢失了}。但是,如果初始化足够丰富和复杂到可以最好地放在
__init__
,而只是将self.foo = foo
移动到{__init__
中,那么这个想法值得记住。在相关问题 更多 >
编程相关推荐