鱼C论坛

 找回密码
 立即注册
查看: 1453|回复: 9

[已解决]关于new和init

[复制链接]
发表于 2021-11-10 00:21:15 | 显示全部楼层 |阅读模式

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

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

x
小甲鱼python课后题043最后一题的代码实现

class Word(str):
'''存储单词的类,定义比较单词的几种方法'''

    def __new__(cls, word):
        # 注意我们必须要用到 __new__ 方法,因为 str 是不可变类型
        # 所以我们必须在创建的时候将它初始化
        if ' ' in word:
            print "Value contains spaces. Truncating to first space."
            word = word[:word.index(' ')] #单词是第一个空格之前的所有字符
        return str.__new__(cls, word)

    def __gt__(self, other):
        return len(self) > len(other)
    def __lt__(self, other):
        return len(self) < len(other)
    def __ge__(self, other):
        return len(self) >= len(other)
    def __le__(self, other):
        return len(self) <= len(other)

这个地方用new的原因是什么?实现了什么样的功能呢?感觉对于new的使用不太了解
最佳答案
2021-11-10 00:42:22
本帖最后由 jackz007 于 2021-11-10 09:22 编辑

          str 类在创建对象的时候,会直接调用 str . __new__(cls , word) 把 word 照原样直接传给新对象。而新定义的 Word 类继承了 str 类,在创建对象的时候,先对传入对象的字符串 word 进行检查,如果发现其中有空格字符存在,会打印一条信息,然后,把位于字符串第一个空格后面的内容从字符串中去掉,然后,用新的字符串调用 str . __new__(cls , word) 去创建对象。例如,如果定义 Word 对象时,使用了字符串 '123 abc' 来初始化对象,那么,对象的内容将是字符串 '123'。
           你可以试一下:
a = Word('123 abc')
print(a)
>>> class Word(str):
    def __new__(cls, word):
        if ' ' in word:
            print("Value contains spaces. Truncating to first space.")
            word = word[:word.index(' ')] #单词是第一个空格之前的所有字符
        return str.__new__(cls, word)

    def __gt__(self, other):
        return len(self) > len(other)
    def __lt__(self, other):
        return len(self) < len(other)
    def __ge__(self, other):
        return len(self) >= len(other)
    def __le__(self, other):
        return len(self) <= len(other)

>>> a = Word('123 abc')
Value contains spaces. Truncating to first space.
>>> print(a)
123
>>> 
        所以,Word 类存在的价值是可以在新建对象的时候,对传入对象的字符串根据需要进行加工,然后采用被加工过的字符串来创建对象。除此以外,Word 类还重载了 str 类的 >、<、>= 和 <= 四个运算符,当两个对象比大小时,比的是字符串的长度,而原始运算符比较的是字符的 ASCII 编码。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-10 00:42:22 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +3 鱼币

本帖最后由 jackz007 于 2021-11-10 09:22 编辑

          str 类在创建对象的时候,会直接调用 str . __new__(cls , word) 把 word 照原样直接传给新对象。而新定义的 Word 类继承了 str 类,在创建对象的时候,先对传入对象的字符串 word 进行检查,如果发现其中有空格字符存在,会打印一条信息,然后,把位于字符串第一个空格后面的内容从字符串中去掉,然后,用新的字符串调用 str . __new__(cls , word) 去创建对象。例如,如果定义 Word 对象时,使用了字符串 '123 abc' 来初始化对象,那么,对象的内容将是字符串 '123'。
           你可以试一下:
a = Word('123 abc')
print(a)
>>> class Word(str):
    def __new__(cls, word):
        if ' ' in word:
            print("Value contains spaces. Truncating to first space.")
            word = word[:word.index(' ')] #单词是第一个空格之前的所有字符
        return str.__new__(cls, word)

    def __gt__(self, other):
        return len(self) > len(other)
    def __lt__(self, other):
        return len(self) < len(other)
    def __ge__(self, other):
        return len(self) >= len(other)
    def __le__(self, other):
        return len(self) <= len(other)

>>> a = Word('123 abc')
Value contains spaces. Truncating to first space.
>>> print(a)
123
>>> 
        所以,Word 类存在的价值是可以在新建对象的时候,对传入对象的字符串根据需要进行加工,然后采用被加工过的字符串来创建对象。除此以外,Word 类还重载了 str 类的 >、<、>= 和 <= 四个运算符,当两个对象比大小时,比的是字符串的长度,而原始运算符比较的是字符的 ASCII 编码。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-10 09:23:56 | 显示全部楼层

回帖奖励 +3 鱼币

__new__是实例化类时第一个自动调用的魔法方法。在这里相当于我们自动用new来加工输入的内容。这些都是好懂的,其实我觉得比较不好懂的是输出str.__new__(cls,word)。这样输出是因为我们知道工厂函数str(实际上也是一个类)可以输入一个对象,比如str(520),来变成"520"。所以我们采用str的魔法方法来代替我们输出一个类对象。你用其它的类来进行这一步不一定可行,前提是这个类要接受参数。经过str.__new__的洗礼,实际上输出的类和"520"是已经绑定在一起的了,不然你print一下__init__()里面的self看看。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-10 09:50:26 | 显示全部楼层

回帖奖励 +3 鱼币

因为你是继承字符串类,字符串类初始是没有你这个判断的,而你要的结果是给的字符串里空格之前的所有字符,所以你要写上你的要求覆盖掉字符串类的__new__,这样你就直接得到你想要的字符串了,我讲的可明白?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-10 10:05:33 | 显示全部楼层

回帖奖励 +3 鱼币

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

使用道具 举报

发表于 2021-11-10 13:10:24 | 显示全部楼层

回帖奖励 +3 鱼币

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

使用道具 举报

 楼主| 发表于 2021-11-10 15:04:22 | 显示全部楼层
jackz007 发表于 2021-11-10 00:42
str 类在创建对象的时候,会直接调用 str . __new__(cls , word) 把 word 照原样直接传给新对象 ...

所以我可以理解成new函数就是在执行init之前就需要执行的一步,作用是创建一个对象,然后init再对创建出的对象初始化?
那这里返回值str.__new__(cls,word)里的word参数代表的是什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-10 15:11:19 | 显示全部楼层
还想问一下,关于不可变类,具体不可变指的是什么呢?比如str,感觉是可以修改的啊?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-10 15:25:21 From FishC Mobile | 显示全部楼层
yudi_zhu 发表于 2021-11-10 15:04
所以我可以理解成new函数就是在执行init之前就需要执行的一步,作用是创建一个对象,然后init再对创建出 ...

        就是你创建对象时使用的那个字符串。看看帖子里那个应用实例。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-10 15:30:35 | 显示全部楼层
jackz007 发表于 2021-11-10 15:25
就是你创建对象时使用的那个字符串。看看帖子里那个应用实例。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-12 20:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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