函数参数和变量用法
分类:
IT文章
•
2023-11-29 20:11:43
1 函数的参数
python的函数参数有四种,分别是位置参数、关键字参数、可变参数和不定长参数.
a.位置参数,有时也称必选参数
# 位置参数就是函数定义该参数的时候,没有进行初始化,调用函数传参的时候需要
# 按位置顺序依次将值赋给位置参数
def fun1(x,n):
return x+n
print(fun1(3,2))
# 5
# 当传入的数的个数和参数个数对不上时,会报错
print(fun1(3))
# TypeError: fun1() missing 1 required positional argument: 'n'
View Code
b.关键字参数
# 关键字参数是在指在函数定义的时候进行初始化的参数,如下c是关键字参数
# 调用函数的时候,关键字参数可以传也可以不传,不传的时候默认用初始化时候的
def fun1(a,b,c=5):
return a+b+c
print(fun1(2,3))
print(fun1(2,3,100))
# 定义函数的时候,必须是位置参数在前,关键字参数在后,否则报错
def fun2(c=3,a=2,b):
return a+b+c
print(fun2(c=2,1,3))
# SyntaxError: non-default argument follows default argumen
View Code
定义关键字参数的时候要注意必须指向不变对象.指向可变对象也可,但要特别注意后续的处理是否真实改变了可变对象
def fun(a,b,c=[]):
a = 5
# print('a的值为')
b.append(['kkk'])
c.append(5)
return c
A = 1
B = [1,2,3]
fun(A, B)
# A是数字是不可变对象,在函数中赋值5后仍未改变
print('A的值未改变:',A)
# B是list是可变对象,在函数中给b添加kkk后,函数外的B也改变了
print('B的值变了:',B)
# A的值未改变: 1
# B的值变了: [1, 2, 3, ['kkk']]
# 由于c赋值为[]是可变对象,则每次调用函数后,都会给c添加一个5,而不会释放
# 如果给c赋值None,None是不变对象,则不会出现这种情况
print(fun(a=1,b=[2],))
print(fun(a=1,b=[2],))
# [5, 5]
# [5, 5, 5]
View Code
当位置参数和关键字参数共用的时候,一定要避免犯下面的错误,位置参数必须要在关键字参数前,且必须要传递,不可省略.
def fun(x,y=2,z=3):
print('x变成了y:',x)
print('y变成了z:',y)
print(z)
x = 555
y = 8
z = 9
fun(y,z)
# 正确写法
fun(x,y,z)
# x变成了y: 8
# y变成了z: 9
# 3
# x变成了y: 555
# y变成了z: 8
# 9
View Code
# return的时候,把函数内x的引用返回来了,并赋值给a
def f(x):
x = 3
print('x', x, id(x))
return x
a = 1
print('原先a的地址:',id(a))
a = f(a)
print('a的地址变了,和函数内x的地址一样', a, id(a))
# 原先a的地址: 9289312
# x 3 9289376
# a的地址变了,和函数内x的地址一样 3 9289376
# x是全局变量,如果在函数内部不加global x的话,函数内部可以调用全局变量x,但不可以直接修改
# 加上的话就可以修改全局变量的值,一句话,不加global只能调用,加上可以直接修改.
def func():
global x
x = 10
x = 5
func()
print('函数把变量值修改了', x)
# 函数把变量值修改了 10
def fun1(m):
m[0] = 20
# 这一步m变成了新的对象,最后返回的而是[4,5,6]
m = [4, 5, 6]
# print(id(m))
return m
l = [1, 2, 3]
# 函数可以通过对可变对象(list dict)内部元素的修改来修改外部变量的值. 注意由于fun1里面没有写global m,所以传过去的m都是局部变量
# 但函数结束调用后却把变量的值给修改了,就是因为执行fun1(l)的时候,把l的引用传给了m,而又因为list是可变对象的缘故,在函数内部修改m,也会改变外面l的值,
t = fun1(l)
# print(id(t))
print(t)
print('l的值变了',l)
# 这一步和上面的不一样,由于用 + 合并list是产生新的对象,所以传参的时候就
# 这里如果用切片法传也一样,因为切片是浅拷贝,所以传过去是新的对象
fun1(l+[2])
print('l的值没变',l)
# [4, 5, 6]
# l的值变了 [20, 2, 3]
# l的值没变 [20, 2, 3]