鱼C论坛

 找回密码
 立即注册
查看: 2278|回复: 17

[已解决]关于__new__方法

[复制链接]
发表于 2021-6-15 13:20:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
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__属性,应该怎么做?
最佳答案
2021-6-15 14:08:07
fc5igm 发表于 2021-6-15 14:03
那我如果想要输入的第一个参数设为一个字符串,第二个参数设为一个整数,第三个参数设为一个浮点数,应该 ...




__new__ 设置的参数都会传递给 __init__ ,你在 new 设置参数相当于在 __init__ 设置

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-6-15 13:28:48 | 显示全部楼层

__new__ 的返回值是返回给 __init__ 的,将实例化后的对象返回给 __init__

而此时你将 test() 函数调用后的返回值设置为 __new__ 的返回值

那么此时 __new__ 返回的是什么对象,__init__ 就接收什么对象

显然你此时传入的是 '3.14' 字符串的实例对象,经过 test 函数后返回 y 是浮点型

则你写的 CapString 类返回的永远是 float 实例对象,而不是 CapString 类的实例对象

你调用 string 是CapString 类的属性,而不是 float 的, float 类没有 string 属性所以报错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-15 13:37:22 | 显示全部楼层
Twilight6 发表于 2021-6-15 13:28
__new__ 的返回值是返回给 __init__ 的,将实例化后的对象返回给 __init__

而此时你将 test() 函数调 ...

我不是很明白。假设我要在new中做计算的话,必然要做int或者float转化。而转化后的值也就必然是int类或者float的实例对象是吗?那是否就是说,我在__new__下,除了引用其他类的__new__,其实是死活都做不了任何l的数据处理的?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-15 13:43:50 | 显示全部楼层
为什么要在new方法里做计算   可以定义其他构造方法 以from开头就行  类似于 datetime.forISOstring  通过字符串创建时间日期可以用这个 不一定非得 datetime()

另外就是  str类super init方法什么也不能做 如果定义init 不要去调用super init  而new方法最好去调用super new
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-15 13:44:42 From FishC Mobile | 显示全部楼层
__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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-15 13:46:11 | 显示全部楼层
fc5igm 发表于 2021-6-15 13:37
我不是很明白。假设我要在new中做计算的话,必然要做int或者float转化。而转化后的值也就必然是int类或者 ...




为什么不直接将这个运算放置于 __init__ 呢

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-15 13:48:37 | 显示全部楼层
fc5igm 发表于 2021-6-15 13:37
我不是很明白。假设我要在new中做计算的话,必然要做int或者float转化。而转化后的值也就必然是int类或者 ...



每个魔法方法都有其对应的职责

对不负责这个职责的魔法方法强加给对方,这不是在做吃力不讨好的事情嘛
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-15 14:03:01 | 显示全部楼层
Twilight6 发表于 2021-6-15 13:48
每个魔法方法都有其对应的职责

对不负责这个职责的魔法方法强加给对方,这不是在做吃力不讨好的事 ...

那我如果想要输入的第一个参数设为一个字符串,第二个参数设为一个整数,第三个参数设为一个浮点数,应该怎么做?
__new__只能返回一个参数吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-15 14:08:07 | 显示全部楼层    本楼为最佳答案   
fc5igm 发表于 2021-6-15 14:03
那我如果想要输入的第一个参数设为一个字符串,第二个参数设为一个整数,第三个参数设为一个浮点数,应该 ...




__new__ 设置的参数都会传递给 __init__ ,你在 new 设置参数相当于在 __init__ 设置

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-15 14:09:14 | 显示全部楼层
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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-15 14:13:32 | 显示全部楼层
fc5igm 发表于 2021-6-15 14:09
是否说__new__方法所做的事情,实际上就是类似于list(),str(),int(),float()这些函数?
另外,请问我在 ...



是否说__new__方法所做的事情,实际上就是类似于list(),str(),int(),float()这些函数?


应该说 list(),str(),int(),float() 都是通过 __new__ 来进行实例对象

另外,请问我在类中是以上函数都一律不能调用吗?


这完全没有冲突,不可变类型参数继承重写一般重写 __new__ 而不重写 __init__
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-15 14:15:58 | 显示全部楼层
hrpzcf 发表于 2021-6-15 13:44
__new__中单纯返回浮点数的话,该CapString的实例a跟CapString是没有关系的
这样

懂了。谢谢。
不过如果我想设置多个呢?
比如参数a是str,参数b是int
还有,既然是引用的str类的__new__方法,那也就代表str的__new__必然是对str的参数进行了一定处理的。
我们可以仿照它,自行设定其他的处理方式吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-15 14:19:26 | 显示全部楼层
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
如果说”没有冲突“,那我有些不太明白,这里为什么会报错。或者说,表达以上函数的意思,请问应该怎么写才是正确的?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-15 14:31:53 | 显示全部楼层
fc5igm 发表于 2021-6-15 14:19
如果说”没有冲突“,那我有些不太明白,这里为什么会报错。或者说,表达以上函数的意思,请问应该怎 ...




我刚刚试着运行了下你的代码,报错的主要原因似乎不是因为 str、int、float 待我再研究研究

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-15 14:34:55 | 显示全部楼层
Twilight6 发表于 2021-6-15 14:24
换种通俗点的解释看看你能不能理解:__new__ 作用就是将 self 是什么告诉给 __init__ 并把定义的参数 ...

我忘记删继承了。抱歉。
然后还有另一个问题。我们对__new__方法的使用,就只能是调用其他类的__new__吗?
难道就不能仿照例如str,list这些类,编写自己的__new__吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-15 14:36:38 | 显示全部楼层
fc5igm 发表于 2021-6-15 14:19
如果说”没有冲突“,那我有些不太明白,这里为什么会报错。或者说,表达以上函数的意思,请问应该怎 ...


因为继承了 str 类,在创建实例前,传入参数还是按照  __new__ 的来进行传入,而因为 str 类的第二个参数为 encoding 编码参数

所以你此时 CapString('abc','10','3.14') ,相当于 encoding = '10' ,因为没有 10 这种编码所以导致报错

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-15 14:44:33 | 显示全部楼层
fc5igm 发表于 2021-6-15 14:34
我忘记删继承了。抱歉。
然后还有另一个问题。我们对__new__方法的使用,就只能是调用其他类的__new__吗 ...



你若是想完完全全写个自己的类,应该需要写 c 语言代码

否则若你的类进行不继承,则无论如何都是默认继承 object 基类

即:
class A:
    pass

等价于:
class A(object):
    pass

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-15 15:10:49 | 显示全部楼层
本帖最后由 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
[] 
请问这里返回的为什么是个空值?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-6-17 06:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表