Python笔记3|参数传递

本文深入探讨了Python中参数传递的机制,包括不可变对象和可变对象的引用传递方式及其实现原理。通过实例演示了如何理解参数传递过程中的内存变化。

Python参数传递

1.什么是参数的传递

请添加图片描述

2.传递不可变对象的引用

请添加图片描述
不可变对象:int、float、字符串、元组、布尔值。

2.1 传递不可变对象的引用的底层逻辑

请添加图片描述
关键:把 a \color{red}{a} a i d \color{orange}{id} id 传给 n \color{purple}{n} n , n \color{purple}{n} n 也指向了 a \color{red}{a} a 所指向的 int 对象,但由于 int 对象不可改变,因此执行n=n+2时,会创建一个新对象存储 “n+2” 的计算结果,再让 n \color{purple}{n} n 指向这个新的计算结果对象。但原本 a \color{red}{a} a n \color{purple}{n} n 共同指向的 int对象未改变,现在 n \color{purple}{n} n 不指向原本的 int对象了,又由 a \color{red}{a} a 单独指向 int对象。

2.1.1 传递不可变对象的底层步骤:

①栈中创建全局变量 a \color{red}{a} a,堆中创建了一个 v a l u e \color{orange}{value} value 100 \color{green}{100} 100 的 int对象。int对象 i d \color{orange}{id} id 给了 全局变量 a \color{red}{a} a, a \color{red}{a} a 指向该列表对象。
在这里插入图片描述

def f1(n):函数定义。
在这里插入图片描述
栈中产生全局变量 f 1 \color{red}{f1} f1 ,堆中产生函数对象,并将函数对象的 i d \color{orange}{id} id f 1 \color{red}{f1} f1
此时 f 1 \color{red}{f1} f1 指向函数对象。参数 n \color{purple}{n} n 尚未用到。

f1(a)调用函数,传递参数 a \color{red}{a} a —> n \color{purple}{n} n
在这里插入图片描述
栈中产生一个栈帧,在栈帧中产生局部变量 n \color{purple}{n} n,由于实参 a \color{red}{a} a 传给了形参 n \color{purple}{n} n,此时局部变量 n \color{purple}{n} n 也指向了 a \color{red}{a} a 所指向的 int对象,此时 a \color{red}{a} a n \color{purple}{n} n 共同指向 int对象。

n=n+200计算结果并创建新对象保存结果,将 n \color{purple}{n} n 指向新对象
在这里插入图片描述
由于 int对象是不可变对象,因此虽然 n \color{purple}{n} n 此时直接指向了int对象也不能在int对象上直接修改。于是现在堆中新建一个 int对象,将n+200的计算结果保存到对象中作为 v a l u e \color{orange}{value} value,再让 n \color{purple}{n} n 指向这个新对象。随后,又只有 a \color{red}{a} a 指向原本的 int对象, n \color{purple}{n} n 不再指向原本的 int对象而是指向了新对象,所以 n \color{purple}{n} n 在函数中的操作就与原本的 int对象没有关系了。

简单测试:
在这里插入图片描述
浅拷贝
请添加图片描述
在这里插入图片描述
test01()参数传递 a \color{red}{a} a --> m \color{purple}{m} m
a \color{red}{a} a m \color{purple}{m} m共同指向元组对象。
在这里插入图片描述
m[2][0] = 888修改元组对象的第三个子对象(即列表对象)的第一值为 i n t ( 888 ) \color{green}{int(888)} int(888)
在这里插入图片描述
最终, a \color{red}{a} a m \color{purple}{m} m 共同指向的元组对象的第二个子对象(列表对象)的第一个元素被修改为 i n t ( 888 ) \color{green}{int(888)} int(888)在这里插入图片描述

3.传递可变对象的引用

在这里插入图片描述
可变对象:列表、字典、自定义的其他可变对象。

3.1 传递可变对象的引用的底层逻辑

请添加图片描述
关键:由于列表是可变对象,那么把 b \color{red}{b} b 列表 i d \color{orange}{id} id 给了栈帧里的局部变量 m \color{blue}{m} m m \color{blue}{m} m 也指向了列表对象。
于是 m \color{blue}{m} m 可以对列表进行直接操作。 m \color{blue}{m} m 消失后,操作结果还在。

3.1.1 传递可变对象的底层步骤:

①栈中创建全局变量 b \color{red}{b} b,堆中创建了一个列表对象,包含 10 \color{green}{10} 10 20 \color{green}{20} 20两个值。列表对象 i d \color{orange}{id} id 给了 全局变量 b \color{red}{b} b, b \color{red}{b} b 指向该列表对象。
在这里插入图片描述
def f2(m):函数定义。
在这里插入图片描述
栈中产生全局变量 f 2 \color{red}{f2} f2 ,堆中产生函数对象,并将函数对象的 i d \color{orange}{id} id f 2 \color{red}{f2} f2
此时 f 2 \color{red}{f2} f2 指向函数对象。参数 m \color{purple}{m} m 尚未用到。

f2(b)调用函数,传递参数 b \color{red}{b} b —> m \color{purple}{m} m
在这里插入图片描述
栈中产生一个栈帧,在栈帧中产生局部变量 m \color{purple}{m} m,由于实参 b \color{red}{b} b 传给了形参 m \color{purple}{m} m,此时局部变量 m \color{purple}{m} m 也指向了 b \color{red}{b} b 所指向的列表对象,此时 b \color{red}{b} b m \color{purple}{m} m 共同指向列表对象。

m.append(30)在列表对象中添加了一个新元素 i n t ( 30 ) \color{green}{int(30)} int(30)
在这里插入图片描述
由于 m \color{purple}{m} m 已经指向了列表对象,因此可以直接对列表对象进行操作。于是成功在 b \color{red}{b} b m \color{purple}{m} m 共同指向的列表对象上添加了元素 i n t ( 30 ) \color{green}{int(30)} int(30)
执行完函数后,栈内的栈帧消失,局部变量 m \color{purple}{m} m 消失,此时又只有 b \color{red}{b} b 指向列表对象。
在这里插入图片描述
此时栈堆情况:
在这里插入图片描述
b \color{red}{b} b 指向的列表对象已经有了三个元素: 10 \color{green}{10} 10 20 \color{green}{20} 20 30 \color{green}{30} 30

简单测试:
在这里插入图片描述

在Databricks Python笔记本中,`%run` 是一个魔法命令,用于运行另一个笔记本。在代码 `%run ./hk_martprep_pre_customer $dd="2025-11-14"` 中: - `%run`:这是Databricks中的魔法命令,专门用于执行其他笔记本。 - `./hk_martprep_pre_customer`:指定了要运行的目标笔记本的相对路径。这里的 `./` 表示当前目录,意味着 `hk_martprep_pre_customer` 笔记本与当前运行此命令的笔记本处于同一目录下。 - `$dd="2025-11-14"`:这是向目标笔记本传递参数的方式。`$` 符号用于标记参数,`dd` 是参数名,`"2025-11-14"` 是参数值。在目标笔记本 `hk_martprep_pre_customer` 中,可以使用这个参数来进行相应的操作。 ### 可能遇到的问题及解决办法 #### 1. 目标笔记本路径错误 如果 `hk_martprep_pre_customer` 笔记本不在当前目录下,就会出现路径错误。解决办法是确认目标笔记本的实际路径,并修改 `%run` 命令中的路径。例如,如果目标笔记本在 `../another_folder` 目录下,命令应改为: ```python %run ../another_folder/hk_martprep_pre_customer $dd="2025-11-14" ``` #### 2. 目标笔记本中未正确接收参数 在目标笔记本 `hk_martprep_pre_customer` 中,需要正确接收和处理传入的参数。可以使用 Databricks 提供的 `dbutils.widgets` 来接收参数。在 `hk_martprep_pre_customer` 笔记本的开头添加以下代码: ```python dbutils.widgets.text("dd", "") dd = dbutils.widgets.get("dd") ``` 这样,目标笔记本就能正确获取并使用传入的参数 `dd`。 #### 3. 环境或库依赖问题 如果目标笔记本依赖特定的库或环境设置,而当前环境中没有满足这些条件,可能会导致运行失败。可以参考之前提到的解决办法,在 Databricks 上安装所需的库,或者修改环境设置。例如,若需要安装 `databricks-sdk`,可以使用以下命令: ```python pip install databricks-sdk ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值