Python中的__new__和__init__

我正在学习Python,到目前为止,我可以告诉下面关于__new____init__

  1. __new__是用于创build对象的
  2. __init__用于对象初始化
  3. __init__之前调用__new__因为__new__返回一个新的实例,之后调用__init__来初始化内部状态。
  4. __new__适用于不可变对象,因为它们一旦被赋值就不能被修改。 所以我们可以返回具有新状态的新实例。
  5. 我们可以使用__new____init__这两个可变对象,因为它的内部状态是可以改变的。

但是我现在还有其他问题。

  1. 当我创build一个新的实例如a = MyClass("hello","world") ,这些参数是如何传递的? 我的意思是我应该如何使用__init____new__构造类,因为它们是不同的,除了缺省的第一个参数,它们都接受任意的参数。
  2. self关键字是在名称方面可以改成别的东西? 但是我想知道cls在名称方面是可以改变的,因为它只是一个参数名称?

我做了一些如下的实验:

 >>> class MyClass(tuple): def __new__(tuple): return [1,2,3] 

我在下面做了:

 >>> a = MyClass() >>> a [1, 2, 3] 

尽pipe我说我想返回tuple ,这个代码工作正常,并返回我[1,2,3] 。 我知道,一旦调用了__new__函数,我们将第一个参数作为我们想要接收的types传递。 我们在谈论Newfunction的权利? 我不知道其他语言返回types以外的绑定types?

我也做了一些其他的事情:

 >>> issubclass(MyClass,list) False >>> issubclass(MyClass,tuple) True >>> isinstance(a,MyClass) False >>> isinstance(a,tuple) False >>> isinstance(a,list) True 

我没有做更多的实验,因为进一步不明亮,我决定在那里停下来,并决定问StackOverflow。

我读的SOpost:

  1. Python对象的创build
  2. Python使用__new__和__init__?

我应该如何使用__init____new__构造类,因为它们是不同的,除了默认的第一个参数,它们都接受任意的参数。

你很less会担心__new__ 。 通常,您只需定义__init__并让默认的__new__传递构造函数参数。

self关键字是在名称方面可以改成别的东西? 但是我想知道cls在名称方面是可以改变的,因为它只是一个参数名称?

两者都只是参数名称,在语言中没有特殊含义。 但是它们的使用在Python社区中是一个非常强大的约定。 大多数Pythonistas将永远不会改变这些上下文中的名称selfcls ,并且会在其他人做的时候感到困惑。

请注意,您使用def __new__(tuple)重新绑定构造函数中的名称tuple 。 当实际实现__new__ ,你会想要这样做

 def __new__(cls, *args, **kwargs): # do allocation to get an object, say, obj return obj 

尽pipe我说我想返回tuple ,这个代码工作正常,并返回我[1,2,3]

MyClass()将具有__new__返回的值。 Python中没有隐式types检查; 程序员有责任返回正确的types(“我们都是在这里同意的成年人 ”)。 能够返回不同于请求的types对于实现工厂很有用:您可以返回所请求types的子类。

这也解释了您观察到的issubclass / isinstance行为:子类关系跟随您使用class MyClass(tuple)isinstance反映您从__new__返回“错误”types。

作为参考,请查看Python语言参考中__new__的要求 。

编辑 :好吧,这是一个可能有用的__new__Eel类跟踪有多less鳗鱼在这个过程中活着,拒绝分配,如果这超过了一些最大值。

 class Eel(object): MAX_EELS = 20 n_eels = 0 def __new__(cls, *args, **kwargs): if cls.n_eels == cls.MAX_EELS: raise HovercraftFull() obj = super(Eel, cls).__new__(cls) cls.n_eels += 1 return obj def __init__(self, voltage): self.voltage = voltage def __del__(self): type(self).n_eels -= 1 def electric(self): """Is this an electric eel?""" return self.voltage > 0 

请注意,有更聪明的方法来完成这一行为。