ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

chap8-fluent python

2022-03-20 18:02:51  阅读:133  来源: 互联网

标签:passengers name python self bus1 fluent print alst chap8


浅拷贝 VS 深拷贝

# In[]
# list 生成一个新的引用对象,只是用alst完成初始化
alst = [1,2,3,4,5]
blst=list(alst)
alst.append(6)
print(blst)

# In[]
alst = [1,2,3,4,5]
blst=alst # 浅拷贝,两者同时变化
alst.append(6)
print(blst)

# In[]
from  copy import copy

alst = [1,2,3,4,5]
blst=alst.copy() # 浅拷贝,两者同时变化
alst.append(6)
print(blst)

# In[]
import  copy 
alst = [1,2,3,4,5]
blst=copy.deepcopy(alst) # 深拷贝,可以认为是用alst初始化一个新的对象
alst.append(6)
print(blst)

 

此处,对可变类型而言,深拷贝其实就是创建了一个新的引用对象,可以认为原来的只是用来做初始化用的。新旧有变化对彼此都没有影响了。浅拷贝可以认为就是起了个别名。

 

 

由于这层原因,当可变类型作为函数参数时,尤其要谨慎处理。首先考虑初始化,如果存在None,该怎么处理,其次如果你不想修改传入参数的值,那么要给类或者函数的属性创建一个副本或者说只是拿传入的参数作为初始化,务必保证,函数内部修改可变类型变量时,形参传入的变量不会受到影响。

'''
the default value of paramter is None
'''
import copy
# tag::BUS_CLASS[]
class Bus:

    def __init__(self, passengers=None):
        if passengers is None:
            self.passengers = []
        else:
            self.passengers = list(passengers)

    def pick(self, name):
        self.passengers.append(name)

    def drop(self, name):
        self.passengers.remove(name)
# end::BUS_CLASS[]

bus1 = Bus(['a','b','c'])
bus2 = copy.copy(bus1)
bus1.pick('d')
bus1.drop('a')
print(bus2.passengers)
bus3= copy.deepcopy(bus1)
print(bus3.passengers)
bus1.pick('a')
bus1.drop('d')
print(bus3.passengers)
print(bus1.passengers)

  

此时如果对默认参数处理不好,会引起很诡异的事情。但是如果用list生成一个新的对象,就会避免这个问题。

'''
Mutable Types as Parameter Defaults:Bad Idea
'''


# tag::HAUNTED_BUS_CLASS[]
class HauntedBus:
    """A bus model haunted by ghost passengers"""

    def __init__(self, passengers=[]):  # <1>
        # should be list function to initialization the attribute
        self.passengers = passengers #list(passengers)  # <2>

    def pick(self, name):
        self.passengers.append(name)  # <3>

    def drop(self, name):
        self.passengers.remove(name)
# end::HAUNTED_BUS_CLASS[]

bus1 = HauntedBus(['Alice', 'Bill'])
print(bus1.passengers)
bus1.pick('Charlie')
bus1.drop('Alice')
print(bus1.passengers)

bus2 = HauntedBus()
bus2.pick('Carrie')
print('bus2.passengers:',bus2.passengers)

bus3 = HauntedBus()
print('bus3.passengers:',bus3.passengers)
bus3.pick('Dave')
print('bus3.passengers:',bus3.passengers)
print(bus2.passengers is bus3.passengers)
print('bus1.passengers:',bus1.passengers)

  

 

还有,这个程序,把形参改变了,本来不该改变的。

'''
here the attribute passengers should be initialized using a list func.

'''

# tag::TWILIGHT_BUS_CLASS[]
class TwilightBus:
    """A bus model that makes passengers vanish"""

    def __init__(self, passengers=None):
        if passengers is None:
            self.passengers = []  # <1>
        else:
            # this can change the passengers when you change self.passengers
            self.passengers = passengers  #<2> 

    def pick(self, name):
        self.passengers.append(name)

    def drop(self, name):
        self.passengers.remove(name)  # <3>
# end::TWILIGHT_BUS_CLASS[]

basketball_team = ['Sue', 'Tina', 'Maya', 'Diana', 'Pat']
bus = TwilightBus(basketball_team)
bus.drop('Tina')
bus.drop('Pat')
print(basketball_team)

  

这几个程序大家都看到了,其实很关键的一个地方是list函数的使用。test =  list(alst)相当于将alst 进行深拷贝,改变alst时,test不会随之改变,改变test时,alst也不会有影响。也可以理解为将alst作为参数,对元素追个转换,生成一个新的list并返回给test。因此,两者之间不再有影响。

标签:passengers,name,python,self,bus1,fluent,print,alst,chap8
来源: https://www.cnblogs.com/jianyingzhou/p/16030784.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有