关于__new__方法
def test(x):x=float(x)
y=x*3.14
return y
class CapString(str):
def __new__(cls,string):
test(string)
return test(string)
def __init__(self,x):
self.string=self
def printstr(self):
print(f"类中self的值:{self}")
>>> a=CapString('3.14')
>>> a.string
Traceback (most recent call last):
File "<pyshell#280>", line 1, in <module>
a.string
AttributeError: 'float' object has no attribute 'string'
我不太明白为什么会报错。a不是成为了一个实例对象吗?为什么又会被认为是个浮点数?
如果我想要在__new__中执行一些指令,而不仅仅是引用其他类的__new__属性,应该怎么做?
__new__ 的返回值是返回给 __init__ 的,将实例化后的对象返回给 __init__
而此时你将 test() 函数调用后的返回值设置为 __new__ 的返回值
那么此时 __new__ 返回的是什么对象,__init__ 就接收什么对象
显然你此时传入的是 '3.14' 字符串的实例对象,经过 test 函数后返回 y 是浮点型
则你写的 CapString 类返回的永远是 float 实例对象,而不是 CapString 类的实例对象
你调用 string 是CapString 类的属性,而不是 float 的, float 类没有 string 属性所以报错 Twilight6 发表于 2021-6-15 13:28
__new__ 的返回值是返回给 __init__ 的,将实例化后的对象返回给 __init__
而此时你将 test() 函数调 ...
我不是很明白。假设我要在new中做计算的话,必然要做int或者float转化。而转化后的值也就必然是int类或者float的实例对象是吗?那是否就是说,我在__new__下,除了引用其他类的__new__,其实是死活都做不了任何l的数据处理的? 为什么要在new方法里做计算 可以定义其他构造方法 以from开头就行类似于 datetime.forISOstring通过字符串创建时间日期可以用这个 不一定非得 datetime()
另外就是str类super init方法什么也不能做 如果定义init 不要去调用super init而new方法最好去调用super new __new__中单纯返回浮点数的话,该CapString的实例a跟CapString是没有关系的
这样
def test(x):
x=float(x)
y=x*3.14
return y
class CapString(float):
def __new__(cls,string):
return super().__new__(cls, test(string))
def __init__(self,x):
self.string=self
def printstr(self):
print(f"类中self的值:{self}")
a = CapString("3.14")
print(a.string)
print(isinstance(a, float), isinstance(a, CapString))
fc5igm 发表于 2021-6-15 13:37
我不是很明白。假设我要在new中做计算的话,必然要做int或者float转化。而转化后的值也就必然是int类或者 ...
为什么不直接将这个运算放置于 __init__ 呢
fc5igm 发表于 2021-6-15 13:37
我不是很明白。假设我要在new中做计算的话,必然要做int或者float转化。而转化后的值也就必然是int类或者 ...
每个魔法方法都有其对应的职责
对不负责这个职责的魔法方法强加给对方,这不是在做吃力不讨好的事情嘛 Twilight6 发表于 2021-6-15 13:48
每个魔法方法都有其对应的职责
对不负责这个职责的魔法方法强加给对方,这不是在做吃力不讨好的事 ...
那我如果想要输入的第一个参数设为一个字符串,第二个参数设为一个整数,第三个参数设为一个浮点数,应该怎么做?
__new__只能返回一个参数吧? fc5igm 发表于 2021-6-15 14:03
那我如果想要输入的第一个参数设为一个字符串,第二个参数设为一个整数,第三个参数设为一个浮点数,应该 ...
__new__ 设置的参数都会传递给 __init__ ,你在 new 设置参数相当于在 __init__ 设置
Twilight6 发表于 2021-6-15 13:48
每个魔法方法都有其对应的职责
对不负责这个职责的魔法方法强加给对方,这不是在做吃力不讨好的事 ...
是否说__new__方法所做的事情,实际上就是类似于list(),str(),int(),float()这些函数?
另外,请问我在类中是以上函数都一律不能调用吗?
class CapString(str):
def __init__(self,x,y,z):
self.str=str(x)
self.int=int(y)
self.float=float(z)
def printstr(self):
print(f"类中self的值:{self}")
a=CapString('abc','10','3.14')
Traceback (most recent call last):
File "D:\python\works\test.py", line 16, in <module>
a=CapString('abc','10','3.14')
TypeError: decoding str is not supported fc5igm 发表于 2021-6-15 14:09
是否说__new__方法所做的事情,实际上就是类似于list(),str(),int(),float()这些函数?
另外,请问我在 ...
是否说__new__方法所做的事情,实际上就是类似于list(),str(),int(),float()这些函数?
应该说 list(),str(),int(),float() 都是通过 __new__ 来进行实例对象
另外,请问我在类中是以上函数都一律不能调用吗?
这完全没有冲突,不可变类型参数继承重写一般重写 __new__ 而不重写 __init__ hrpzcf 发表于 2021-6-15 13:44
__new__中单纯返回浮点数的话,该CapString的实例a跟CapString是没有关系的
这样
懂了。谢谢。
不过如果我想设置多个呢?
比如参数a是str,参数b是int
还有,既然是引用的str类的__new__方法,那也就代表str的__new__必然是对str的参数进行了一定处理的。
我们可以仿照它,自行设定其他的处理方式吗? Twilight6 发表于 2021-6-15 14:13
应该说 list(),str(),int(),float() 都是通过 __new__ 来进行实例对象
class CapString(str):
def __init__(self,x,y,z):
self.str=str(x)
self.int=int(y)
self.float=float(z)
def printstr(self):
print(f"类中self的值:{self}")
a=CapString('abc','10','3.14')
Traceback (most recent call last):
File "D:\python\works\test.py", line 11, in <module>
a=CapString('abc','10','3.14')
TypeError: decoding str is not supported
如果说”没有冲突“,那我有些不太明白,这里为什么会报错。或者说,表达以上函数的意思,请问应该怎么写才是正确的? fc5igm 发表于 2021-6-15 14:19
如果说”没有冲突“,那我有些不太明白,这里为什么会报错。或者说,表达以上函数的意思,请问应该怎 ...
我刚刚试着运行了下你的代码,报错的主要原因似乎不是因为 str、int、float 待我再研究研究
Twilight6 发表于 2021-6-15 14:24
换种通俗点的解释看看你能不能理解:__new__ 作用就是将 self 是什么告诉给 __init__ 并把定义的参数 ...
我忘记删继承了。抱歉。
然后还有另一个问题。我们对__new__方法的使用,就只能是调用其他类的__new__吗?
难道就不能仿照例如str,list这些类,编写自己的__new__吗? fc5igm 发表于 2021-6-15 14:19
如果说”没有冲突“,那我有些不太明白,这里为什么会报错。或者说,表达以上函数的意思,请问应该怎 ...
因为继承了 str 类,在创建实例前,传入参数还是按照__new__ 的来进行传入,而因为 str 类的第二个参数为 encoding 编码参数
所以你此时 CapString('abc','10','3.14') ,相当于 encoding = '10' ,因为没有 10 这种编码所以导致报错
fc5igm 发表于 2021-6-15 14:34
我忘记删继承了。抱歉。
然后还有另一个问题。我们对__new__方法的使用,就只能是调用其他类的__new__吗 ...
你若是想完完全全写个自己的类,应该需要写 c 语言代码
否则若你的类进行不继承,则无论如何都是默认继承 object 基类
即: class A:
pass
等价于:
class A(object):
pass
本帖最后由 fc5igm 于 2021-6-15 15:13 编辑
Twilight6 发表于 2021-6-15 14:44
你若是想完完全全写个自己的类,应该需要写 c 语言代码
否则若你的类进行不继承,则无论如何都是 ...
class Test(list):
def __new__(cls,*x):
print(x)
return list.__new__(cls,x)
def __init__(self,*x):
self.L=self
>>> a=Test('a','b','c')
('a', 'b', 'c')
>>> a
[]
>>> a.L
[]
请问这里返回的为什么是个空值?
页:
[1]