Python函数参数传递机制:可变与不可变对象详解

林舟
林舟
发布时间:2026-10-14| 5人浏览过
原创

本文深入解析Python函数参数传递机制,重点区分可变与不可变对象在传参时的行为差异。通过代码示例说明整型、元组等不可变对象无法在函数内修改原值,而列表、字典等可变对象可被修改。掌握此原理有助于避免常见的变量作用域陷阱,编写更健壮的Python代码。

如下所示:


#抽象 (函数)
 
# 1、callable  判断一个对象是否可以被调用
x = 1
def y():
    return None
callable(y)  # y可以被调用
callable(x)  # x不可以被调用
 
 
# 2、当函数没有return时   函数将默认返回None
# 3、放在函数开头的字符串成为文档字符串   如下:
def square(x):
    'my name is hexianmin'   #这个为文档字符串   将作为函数的一部分存储起来
    return x*x
 
# 4、函数中的 '传值'  和  '传地址'       切片列表产生的是一个相等但不相同的副本(即两个列表存储地址不一样)
# 传值:   调用函数时传 变量   eg: x = 1   change(x)
# 传地址:   调用函数时传  列表(在这里说明:元组不可以改变  传过去也不能修改)   eg: x = list('pyhon')   change(x)
 
 
# 函数参数 : 1、位置参数   2、关键字参数  
# 1、位置参数 :实参与形参的对应关系为 '一一对应' 的关系  实参的前后位置决定了形参接到的值
# 2、关键字参数 :由指定关键字去给形参传值(或者传地址)  像字典一样 key-value 的对应关系
# 注意: 1、二者不可以冲突   2、关键字参数和位置参数可以混在一起用,优先关键字参数,剩下的按照位置一一对应
 
 
#  *  /  **  的妙用 :收集参数  和   分配参数   的作用
# 收集参数:   *  : 将  多余的  一般的对象(位置参数,字典也将作为位置参数)收集成元组类型       ** : 将  多余的  关键字参数  收集为字典类型
# 分配参数:   *  : 将元组类型的参数分配给形参                             ** : 将字典类型的参数分配给形参
 
 
# 收集参数:
def print_params_1(x, y, z=3, *pospar, **keypar):  #注意这里的 z=3 是给z赋一个默认值  当调用函数时没有给z赋值时使用  但是一旦调用时给z赋值了  z就不用默认值了                            
    print(x, y, z)
    print(pospar)   #在函数里面使用时 : 1、不带星号(*) 是 一个元组   2、带星号(*) 是 取元组中的每个值出来
    print(keypar)   #在函数里面使用时 : 1、不带星号(**) 是 一个字典(但是取不了值出来)  2、带一个星号(*) 是 取字典中的每个关键字(key)出来   3、带两个星号 会报错
print_params_1(1, 2, 4, 5, 6, 7, foo=1, bar=2)
 
 
# 分配参数:
def foo(x, y, z, m=0, n=0):
    print(x, y, z)
    print(m)
    print(n)
    return -1
def call_foo(*args, **kwds):  #收集参数
    print('calling foo!')
    foo(*args, kwds)   #分配参数   这里如果用foo(*args, **kwds)  **kwds会报错
x1 = 1
y1 = 2
z1 = 3
d = {
    'm1': 4,
    'n1': 5
}
print(call_foo(x1, y1, z1, d1=1, d2=2))  #调用的时候  一个字典是作为一个位置参数的  
 
 
 
# 作用域 :1、全局变量    2、局部变量
 
# 注意: 在局部函数(局部函数中默认变量都是局部变量)中使用全局变量: 1、只使用一次(且重名了)   2、声明后使用(声明后就是全局变量了)
# 1、只使用一次(且重名了):
para = 1
def combine(para):
    print(para,globals()['para'])    # globals()['para']   
combine(2)
 
# 2、声明后使用(声明后就是全局变量了):
xx = 2
def change_global():
    global xx     #声明后就是全局变量了
    xx = xx +2
    print(xx)
change_global()
 
# 3、vars(): 赋值其实是一个看不见的字典   使用后返回的就是一个字典
x11 = 1
x22 = vars() 
print(x22['x11'])
 
# 4、 vars()  globals()   locals()  使用后都是返回一个字典
 
 
# 作用域嵌套
def multi(fac):
    def multiFac(num):   # multiFac(num)函数被称为 : 闭包
        return num * fac
    return multiFac
dou = multi(2)   #返回的 dou 现在是一个函数( multiFac(num)函数 )
dou(3)  #这样相当于调用 multiFac(3)
 
 
# list(map(str,range(10)))  与  [str(i) for i in range(10)]  是等价的
# filter(lambda x: x.isalnum, seq)        
#from functools import reduce       reduce(lambda x,y: x+y, numbers)
 
# map   filter   reduce  

补充:python参数传递问题(参数传出)

变量、对象与类型关系

Python作为动态类型语言,无需预先声明变量类型。变量的类型与其值在赋值瞬间完成初始化。关键在于,Python中的类型归属于对象本身,而非变量名。

例如:


a=2
b=[1,2]

这表示将整型对象2赋值给变量a,将列表对象[1,2]赋值给变量b。

这意味着,当通过赋值号将不同类型的Python对象赋给变量时,才完成该变量的初始化,使变量指向特定类型的对象。

函数

不可更改参数传递

若需进行参数传递,定义函数前必须确保参数变量已声明,否则可能引发“global name 'abun1' is not defined”错误,尽管该声明过程可以是隐式的。

例如执行a=2或a={}时,在赋值的瞬间完成变量类型的初始化,即完成了变量的声明。

但需特别注意,Python中的int、long、bool、float、tuple()等对象均属于不可变类型。因此,在参数传递过程中,无法通过函数内部操作直接修改这些类型变量的原始值。

例如:


def tmpF(a):
    a=10
nint=2
tmpF(nint)
print(nint) #结果仍是2

由于变量nint指向整型对象2,调用函数tmpF()时,因整型对象不可变,函数内部新建了一个值为10的整型对象并让局部变量a指向它。因此,外部的nint仍指向原整型对象2,其值未发生改变。

可更改参数传递

若在定义函数时希望利用参数输出处理后的变量,必须使用可变对象,如list、dict等。

例如:


def tmpF(a):
    a.append(2)
nx=[]
tmpF(nx)
print(nx) #nx=[2]

因为list是可更改类型的对象,调用函数tmpF()时,对该list对象进行了修改(如append操作),而变量nx始终指向同一个对象,因此nx的值随之改变。

所以,函数可以通过传递可变类型对象,实现参数的“输出”效果。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。