Python由数据结构树引发的思考(可变对象/不可变对象,深拷贝/浅拷贝)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shu_8708/article/details/79946502

数据类型二叉树之前就有写过,我曾一直认为,因为Python没有指针操作,所有实现起来会有麻烦,应该会用数组插入数组的方法进行实现。然后进行了尝试:

class Node:
    date=None
    left=None
    right=None

class Tree:
    def __init__(self):
        self.Root=Node()
        self.index=0
    def Create_Tree(self,DateArray,ptr):
        print('index',self.index)
        print('date',DateArray[self.index])
        if DateArray[self.index]=='#':
            ptr.date='#'
            self.index+=1
            return
        ptr.date=DateArray[self.index]
        self.index+=1
        ptr.left=Node()
        ptr.right=Node()
        self.Create_Tree(DateArray,ptr.left)
        self.Create_Tree(DateArray,ptr.right)
    def display(self,ptr):
        if ptr.date=='#':
            print('#')
            return
        print(ptr.date)
        self.display(ptr.left)
        self.display(ptr.right)


if __name__=="__main__":
    x=Tree()
    dates="ab##c##"
    print(dates)
    x.Create_Tree(DateArray=dates,ptr=x.Root)
    x.display(x.Root)
    print("over")

‘#’字符为空节点判断标志,这里任然实现了通过前序遍历的方法创建树,但是值得思考的是这里:

self.Create_Tree(DateArray,ptr.left)
self.Create_Tree(DateArray,ptr.right)

这里将Node的左节点和右节点作为参数传输函数中,如果按照C/C++的逻辑应该是拷贝一份变量传入,所以后面的赋值都没有意义,这里就存在了可变对象和不可变对象的问题。
再看一个例子:

class Node:
    date=None
    Next=None

def Fixed(ptr):
    print(id(ptr))
    ptr.date="test"
    ptr.Next=None
    print(id(ptr))

def Change(x):
    print('change',id(x))
    x=11
    print(id(x))
if __name__=="__main__":
    x=Node()
    x.date="fantasy"
    Fixed(x)
    print(x.date)
    c=22
    Change(c)
    print(c)

很清楚的知道,int类型的c通过函数修改其值需要加global所以,c不会改变
但是这里x通过函数属性被修改了,这两个对象在函数调用过程中地址均未发生改变,之所以会右这样的不同原因就在于int对象是不变对象,在c值被修改后吗,会发现c的地址也发生了改变。

**可变对象:**list,dict,set等,不会发生拷贝,直接对对象进行赋值。
**不可变对象:**int,float,string,tuple等,赋值时会重新开辟一段内存空间进行复制,然后变量再绑定到新的内存空间。

如果希望将对象最为参数传入函数并且不被修改,则需要进行拷贝,感觉就像人为的做了C/C++传参的操作,操作如下:

f __name__=="__main__":
    x=Node()
    x.date="fantasy"
    print('x',id(x))
    y=copy.copy(x)
    print('y',id(x))
    Fixed(y)
    print(x.date)

此时对象x就没有被函数改变,可以看到x和y地址已经不同。
这里出现疑问deepcopy和copy同时实现了对对象的拷贝工作,其区别在哪里。
copy仅拷贝当前对象,deepcopy则拷贝当前对象及其子对象,也就说deepcopy后的对象与拷贝对象不再想干,而浅拷贝对象的子对象任然会受到拷贝对象子对象的影响。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页