关于new和init
小甲鱼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的使用不太了解 本帖最后由 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 编码。 __new__是实例化类时第一个自动调用的魔法方法。在这里相当于我们自动用new来加工输入的内容。这些都是好懂的,其实我觉得比较不好懂的是输出str.__new__(cls,word)。这样输出是因为我们知道工厂函数str(实际上也是一个类)可以输入一个对象,比如str(520),来变成"520"。所以我们采用str的魔法方法来代替我们输出一个类对象。你用其它的类来进行这一步不一定可行,前提是这个类要接受参数。经过str.__new__的洗礼,实际上输出的类和"520"是已经绑定在一起的了,不然你print一下__init__()里面的self看看。{:10_279:}{:10_279:}{:10_279:} 因为你是继承字符串类,字符串类初始是没有你这个判断的,而你要的结果是给的字符串里空格之前的所有字符,所以你要写上你的要求覆盖掉字符串类的__new__,这样你就直接得到你想要的字符串了,我讲的可明白? {:10_254:} {:10_256:} jackz007 发表于 2021-11-10 00:42
str 类在创建对象的时候,会直接调用 str . __new__(cls , word) 把 word 照原样直接传给新对象 ...
所以我可以理解成new函数就是在执行init之前就需要执行的一步,作用是创建一个对象,然后init再对创建出的对象初始化?
那这里返回值str.__new__(cls,word)里的word参数代表的是什么? 还想问一下,关于不可变类,具体不可变指的是什么呢?{:10_269:}比如str,感觉是可以修改的啊? yudi_zhu 发表于 2021-11-10 15:04
所以我可以理解成new函数就是在执行init之前就需要执行的一步,作用是创建一个对象,然后init再对创建出 ...
就是你创建对象时使用的那个字符串。看看帖子里那个应用实例。 jackz007 发表于 2021-11-10 15:25
就是你创建对象时使用的那个字符串。看看帖子里那个应用实例。
哦哦哦,懂了
页:
[1]