码迷,mamicode.com
首页 > 编程语言 > 详细

Python的高级特性1:容易忽略的不可变类型

时间:2015-07-18 18:27:49      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

python中有一些容易忽略的不可变类型(str,integer,tuple,None)

#错误演示
In [45]: def demo(lst=[]): ....: lst.append("hello") ....: return lst ....: In [46]: demo() Out[46]: [hello] In [47]: demo() Out[47]: [hello, hello]

廖雪峰的python教程有提到这一块,但并没有太细致。在这里,由于lst是一个可变参数,而demo在初始化时lst参数指向一个[]的内存空间,之后每一次调用,[]这个内存空间都append一个“hello”,而由于lst依然指向这个内存空间,所以就会看到demo函数调用的奇怪现象,解决问题的办法就是引入不可变类型。

#正确演示

In [54]: def demo(lst=None):
   ....:     lst=[]
   ....:     lst.append("hello")
   ....:     return lst
   ....: 

In [55]: demo()
Out[55]: [hello]

In [56]: demo()
Out[56]: [hello]

在正确演示中,将lst初始化为None,这样lst就是一个不可变参数,但是不能直接对lst直接使用append,因为只有list才有append方法,因此需要将lst进行真正的初始化:lst=[]

在这里,我还想延伸一下关于__new__的用法。为什么要放在这里说,待会看了这个例子就会明白。

class Word(str):
    def __new__(cls, word):
        word = word.replace(" ","")
        return str.__new__(cls,word)

    def __init__(self,word):
        self.word = word

def __eq__(self, other): return len(self)==len(other)

def main(): a=Word("foorrrdd ") b=Word("sswwss ") print a==b
if __name__ == __main__: main()

在这段代码里,可以看到Word类继承自str,str是一个不可变类型,因此需要使用到__new__这个魔术方法,在这里对word这个形参进行了预处理,然后预处理后的形参word会传递给__init__。由于此例此种情形中,a,b指向的是不同的内存空间,即使不用__new__也不会因为实参的传入导致上面例子出现不断追加的情况,但显然这会是一种更为安全的写法。

 

(ps:我不是很确定None是不是一个不可变类型,这篇文章只是个人的理解,如果有误,恳请指正。)

 

Python的高级特性1:容易忽略的不可变类型

标签:

原文地址:http://www.cnblogs.com/alexkn/p/4657306.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!