|
发表于 2021-7-15 15:59:04
|
显示全部楼层
本帖最后由 阿奇_o 于 2022-1-2 17:37 编辑
其实你要先明白,背后它有很多“默认”会去执行的方法,
如 即使 你不写任何,单单写 class MyClass: pass
那么,当 obj = MyClass() , 也一样 会先调用 __new__() , 再 __init__() 等,只是 调用的是 其最终父类object类的__new__() 和 __init__() 以及打印是调用__str__()
但 你 class C2F(float): ... 就是继承float类,同时也继承object这个最大的总父类。
当 你 自己 “重写”__new__或__init__或__str__的特殊方法时, 就会 优先调用你写的,而不再往上找父类的,
如 class C2F(float): ... 你直接继承float类,并调用了它的float.__new__(cls, ...) 于是它就按这个执行并返回给 你写的__init__(self, ...)
至于参数的问题,__new__的 cls参数是固定的,且必须是放在第一个(这种叫“静态类方法”,知道怎么写就行了) arg只是个形参的名字,
你可以换成value或任意合适唯一的名字,对应 先用类构造对象的实参,如 C2F(10)里的10,或 MyClass(10) ,
只不过你调用时,写 C2F(..)它直接提示和显示的形参是 __int__的形参名,你不能写别的形参名。。 比如,
- >>> class c2f(float):
- def __new__(cls, value=0):
- return float.__new__(cls, value*1.8+32)
- def __init__(self, value):
- print(self)
- print(value)
-
- >>> a = c2f(10)
- 50.0
- 10
- >>> b = c2f(value=20)
- 68.0
- 20
- >>> c = c2f(arg=20) # 报错,你必须 用 __init__里定义的形参。即使你把__new__的形参改为叫 arg , 也会报错。
- Traceback (most recent call last):
- File "<pyshell#10>", line 1, in <module>
- c = c2f(arg=20)
- TypeError: __new__() got an unexpected keyword argument 'arg'
- >>>
- 由此可见,__new__的参数,除了 固定的cls, 其他参数 都来自 __init__的参数。
复制代码
嗯,这个我也是 新发现:__new__的参数,除了固定的cls, 其他参数 都来自 __init__的参数。
嗯,我应该讲明白了。。
-------------
补充:2022年1月2日17:26:59
现在仔细看看,这里关于参数的说法,其实是错误的。应该是 除cls外,__new__的其他参数会传给__init__。
这样就要求,当使用关键字参数时,必须它们所定义的形参名要相同。
否则,无法成功创建实例(这时__new__的参数错误),或无法完成初始化(这时__init__的参数错误)。
|
|