我应该如何使用来构建类__init__
and __new__
因为它们是不同的,并且除了默认的第一个参数之外都接受任意参数。
只有极少数情况下您才需要担心__new__
。通常,您只需定义__init__
并让默认值__new__
将构造函数参数传递给它。
self
关键字是在名称方面可以更改为其他内容吗?但我想知道cls
就名称而言,是否可以更改为其他名称,因为它只是参数名称?
两者都只是参数名称,在语言中没有特殊含义。但他们的用途是veryPython 社区中的强大约定;大多数 Python 爱好者都会never更改名称self
and cls
在这些情况下,当其他人这样做时会感到困惑。
请注意,您使用def __new__(tuple)
重新绑定名称tuple
构造函数内部。实际实施时__new__
,你会想要这样做
def __new__(cls, *args, **kwargs):
# do allocation to get an object, say, obj
return obj
虽然我说过我想回来tuple
,这段代码工作正常并返回给我[1,2,3]
.
MyClass()
将具有以下价值__new__
返回。 Python 中没有隐式类型检查;返回正确的类型是程序员的责任(“我们都是同意的成年人 http://mail.python.org/pipermail/tutor/2003-October/025932.html此处“)。能够返回与请求不同的类型对于实现工厂很有用:您可以返回请求类型的子类。
这也解释了issubclass
/isinstance
您观察到的行为:子类关系来自您的使用class MyClass(tuple)
, the isinstance
反映您从返回“错误”类型__new__
.
作为参考,请查看要求__new__ http://docs.python.org/reference/datamodel.html#object.__new__ in the Python 语言参考.
Edit:好的,这是一个可能有用的示例__new__
。班上Eel
跟踪在此过程中有多少条鳗鱼还活着,如果超过某个最大值,则拒绝分配。
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
请注意,有更聪明的方法 https://stackoverflow.com/questions/674304/pythons-use-of-new-and-init/674345#674345来完成这个行为。