结论:num ,tuple 作为参数,自身不会因为函数的原因而改变,list 为可变量,会因为函数变而变。
def f(a, b):
a += b
return a
if __name__ == "__main__":
x = 1
y = 2
result = f(x, y)
print("*"*40)
print("num 数字作为参数")
print(f"x= {x}")
print(f"y= {y}")
print(f"result={result}")
print("*"*40,'\n')
x1 = [1,2]
y1 = [3,4]
result1 = f(x1, y1)
print("*"*40)
print("list 数字作为参数")
print(f"x1= {x1}")
print(f"y1= {y1}")
print(f"result1={result1}")
print("*"*40,'\n')
x2 = (1,2)
y2 = (3,4)
result2 = f(x2, y2)
print("*"*40)
print("tuple 数字作为参数")
print(f"x2= {x2}")
print(f"y2= {y2}")
print(f"result2={result2}")
print("*"*40)
****************************************
num 数字作为参数
x= 1
y= 2
result=3
****************************************
****************************************
list 数字作为参数
x1= [1, 2, 3, 4]
y1= [3, 4]
result1=[1, 2, 3, 4]
****************************************
****************************************
tuple 数字作为参数
x2= (1, 2)
y2= (3, 4)
result2=(1, 2, 3, 4)
没有指定初始乘客的HauntedBus实例会共享同一乘客列表
class HauntedBus:
"""备受幽灵乘客折磨的校车"""
# 默认值为list ,会导致新实例化的bus2 & bus3共享同一列表
def __init__(self, passengers=[]):
# 设置可变类型作为参数默认值
self.passengers = passengers
def pick(self, name):
self.passengers.append(name)
def drop(self, name):
try:
self.passengers.remove(name)
except ValueError as e:
print("error for ", e)
if __name__ == "__main__":
bus1 = HauntedBus(['Alice', 'Bill'])
print(f"bus1.passengers={bus1.passengers}")
bus1.pick('Charlie')
bus1.drop('Alice')
print(f"bus1.passengers={bus1.passengers}")
bus2 = HauntedBus()
bus2.pick('Carrie')
print(f"bus2.passengers={bus2.passengers}")
bus3 = HauntedBus()
print(f"bus3.passengers={bus3.passengers}")
bus1.passengers=['Alice', 'Bill']
bus1.passengers=['Bill', 'Charlie']
bus2.passengers=['Carrie'] # bus2 和bus3 没有默认值的情况下共享同一列表
bus3.passengers=['Carrie']
class TwilightBus:
"""让乘客销声匿迹的校车"""
def __init__(self, passengers=None):
if passengers is None:
self.passengers = []
else:
# 用 passengers 作为参数传入,会导致self.passengers,
# passengers ,basketball_team,
# 都为列表['sue', 'tina', 'maya', 'diana', 'pat'] 的别名,所以任一改变,
# 均可改变['sue', 'tina', 'maya', 'diana', 'pat']的值
self.passengers = passengers
def pick(self, name):
self.passengers.append(name)
def drop(self, name):
try:
self.passengers.remove(name)
except ValueError as e:
print("Error for ", e)
if __name__ == "__main__":
basketball_team = ['sue', 'tina', 'maya', 'diana', 'pat']
bus = TwilightBus(basketball_team)
print(f"before : basketball_team={basketball_team}")
bus.drop('tina')
bus.drop('jason')
bus.drop('pat')
print(f"after : basketball_team={basketball_team}")
before : basketball_team=['sue', 'tina', 'maya', 'diana', 'pat']
Error for list.remove(x): x not in list
# 列表在经过函数后居然发生变化
after : basketball_team=['sue', 'maya', 'diana']
class TwilightBus:
"""让乘客销声匿迹的校车"""
def __init__(self, passengers=None):
if passengers is None:
self.passengers = []
else:
# 用 passengers 作为参数传入,会导致self.passengers,passengers ,basketball_team,
# 都为列表['sue', 'tina', 'maya', 'diana', 'pat'] 的别名,所以任一改变,均可改变['sue', 'tina', 'maya', 'diana', 'pat']的值
self.passengers = passengers
def pick(self, name):
self.passengers.append(name)
def drop(self, name):
try:
self.passengers.remove(name)
except ValueError as e:
print("Error for ", e)
class OkBus:
def __init__(self, passengers=None):
if passengers is None:
self.passengers = []
else:
# 创建 passengers 的副本,并且赋值给 self.passengers
# 重点 list(passengers)!!!!!!!
self.passengers = list(passengers)
def pick(self, name):
self.passengers.append(name)
def drop(self, name):
try:
self.passengers.remove(name)
except ValueError as e:
print("Error for ", e)
if __name__ == "__main__":
basketball_team = ['sue', 'tina', 'maya', 'diana', 'pat']
bus = TwilightBus(basketball_team)
print("*"*40)
print(f"before : basketball_team={basketball_team}")
bus.drop('tina')
bus.drop('jason')
bus.drop('pat')
print(f"after : basketball_team={basketball_team}")
print("*"*40)
basketball_teamok = ['sue', 'tina', 'maya', 'diana', 'pat']
busok = OkBus(basketball_teamok)
print(f"before : basketball_teamok={basketball_teamok}")
busok.drop('tina')
busok.drop('pat')
print(f"after : basketball_teamok={basketball_teamok}")
print("*"*40)
****************************************
# self.passengers = passengers 的结果,会影响原来的参数列表 basketball_team
before : basketball_team=['sue', 'tina', 'maya', 'diana', 'pat']
Error for list.remove(x): x not in list
after : basketball_team=['sue', 'maya', 'diana']
****************************************
# self.passengers = list(passengers) 的结果,不影响 原来的参数列表 basketball_team
before : basketball_teamok=['sue', 'tina', 'maya', 'diana', 'pat']
after : basketball_teamok=['sue', 'tina', 'maya', 'diana', 'pat']
****************************************
当函数用参数时,尽量用不可变作为形参,比如数字,元组,如果用可变类型作为变量,会导致传入的值变化,为了解决这个问题,判断参数传入的是不是None,并且重新创建新的list
class Bus:
def __init__(self,passengers=None):
if passengers is None:
self.passengers = []
else:
self.passengers = list(passengers)