Python参数传递 - 快递小包裹!¶
1. 什么是参数传递?让我们一起想象...¶
想象你是一个快递员!当你送快递时,有时送的是一张照片(不能改变的东西),有时送的是一个玩具箱(可以往里面加东西)。Python的参数传递就像送快递: - 有些东西送过去后不能改变(数字、字符串) - 有些东西送过去后可以改变(列表、字典)
2. 让我们玩个快递游戏!¶
2.1. 送照片 - 不可变参数¶
def change_number(num):
print(f"收到的数字是:{num}")
num = 100 # 试图改变数字
print(f"尝试改变后:{num}")
# 寄出一个数字
my_number = 42
print(f"原始数字是:{my_number}")
change_number(my_number)
print(f"送回来的数字还是:{my_number}") # 数字没有改变!
2.2. 送玩具箱 - 可变参数¶
def add_toy(toy_box):
print(f"收到的玩具箱里有:{toy_box}")
toy_box.append("小熊") # 往玩具箱里加东西
print(f"加了新玩具后:{toy_box}")
# 准备一个玩具箱
my_toys = ["积木", "小车"]
print(f"原始玩具箱:{my_toys}")
add_toy(my_toys)
print(f"送回来的玩具箱:{my_toys}") # 玩具箱里多了东西!
3. 不同类型的快递¶
3.1. 不能改变的快递(不可变类型)¶
def try_change_values(number, text, point):
print("试图改变收到的快递...")
number = 200
text = "新文字"
point = (3, 3)
print(f"在函数里:number={number}, text={text}, point={point}")
# 寄出不同类型的快递
my_number = 100
my_text = "你好"
my_point = (1, 1)
try_change_values(my_number, my_text, my_point)
print(f"原来的东西都没变:")
print(f"number={my_number}, text={my_text}, point={my_point}")
3.2. 可以改变的快递(可变类型)¶
def modify_collections(list_box, dict_box, set_box):
print("修改收到的快递...")
list_box.append("新玩具")
dict_box["新key"] = "新value"
set_box.add("新元素")
print(f"在函数里改变后:")
print(f"list_box={list_box}")
print(f"dict_box={dict_box}")
print(f"set_box={set_box}")
# 准备可以改变的快递
my_list = ["旧玩具"]
my_dict = {"旧key": "旧value"}
my_set = {"旧元素"}
modify_collections(my_list, my_dict, my_set)
print(f"快递送回来后都变了:")
print(f"my_list={my_list}")
print(f"my_dict={my_dict}")
print(f"my_set={my_set}")
4. 特殊的快递方式¶
4.1. 复制一份再送(使用切片或copy)¶
def safe_add_toy(toy_box):
# 复制一份玩具箱
new_box = toy_box.copy()
new_box.append("新玩具")
return new_box
# 原始玩具箱
my_toys = ["玩具1", "玩具2"]
print(f"原始玩具箱:{my_toys}")
# 获得一个新的玩具箱
new_toys = safe_add_toy(my_toys)
print(f"原来的玩具箱:{my_toys}")
print(f"新的玩具箱:{new_toys}")
4.2. 深度复制(使用deepcopy)¶
from copy import deepcopy
def modify_nested_box(box):
# 深度复制一个盒子
new_box = deepcopy(box)
new_box["外层"]["里层"].append("新玩具")
return new_box
# 准备一个有内外层的盒子
my_box = {
"外层": {
"里层": ["玩具1", "玩具2"]
}
}
print(f"原始盒子:{my_box}")
new_box = modify_nested_box(my_box)
print(f"原来的盒子:{my_box}")
print(f"新的盒子:{new_box}")
5. 有趣的例子¶
5.1. 魔法糖果盒¶
def magic_candy_box(candies, new_candy):
print(f"魔法糖果盒里现在有:{candies}")
if isinstance(new_candy, str):
# 如果是字符串(不可变),变成大写也不会影响原来的
new_candy = new_candy.upper()
candies.append(new_candy)
print(f"加入新糖果后:{candies}")
# 准备糖果盒
my_candies = ["巧克力", "棒棒糖"]
new_candy = "果冻"
print(f"原始糖果盒:{my_candies}")
magic_candy_box(my_candies, new_candy)
print(f"送回的糖果盒:{my_candies}")
print(f"原始新糖果还是:{new_candy}") # 新糖果没变
5.2. 彩虹画板¶
def add_colors(palette):
print(f"画板上现在的颜色:{palette}")
# 往画板上加颜色
palette["红色"] = "鲜红"
palette["蓝色"] = "天蓝"
print(f"加了新颜色后:{palette}")
# 准备画板
my_palette = {"黄色": "金黄"}
print(f"原始画板:{my_palette}")
add_colors(my_palette)
print(f"画板变成了:{my_palette}")
6. 小贴士¶
- 记住参数传递的规则:
- 不可变类型:就像照片,送过去后不能改变原件
- 可变类型:就像玩具箱,可以往里面加东西
-
想要保护原件,就要复制一份再送
-
不可变类型有:
- 数字(整数、浮点数)
- 字符串
- 元组
-
布尔值
-
可变类型有:
- 列表
- 字典
- 集合
记住:参数传递就像送快递,要知道什么快递可以改变,什么快递不能改变。这样就能写出更好的程序啦!