第十二章:函数(python version 3.7.2)
参数传递
- 位置传递.
- 关键字传递.
- 参数默认值.
- 包裹传递(包裹位置传递,包裹关键字传递).
针对这四种传递方式,需要在定义阶段和调用阶段分别讨论:
位置传递:
定义阶段,用
位置参数
定义函数,比如:
def add(x,y):#x,y就是位置参数
return x + y
调用阶段,传入和函数定义时数量和顺序一致的参数,位置传递
通过实参的位置给形参赋值
.
add(10,20) # 传入对应的参数来调用函数
关键字传递:
定义阶段,与位置参数一样,使用形参定义.
def sub(x,y):
return x - y
调用阶段,使用定义时的形参作为关键词并赋予其相应的值组成关键字参数.比如:
sub(y = 20, x = 100)# 关键字传递是根据每个参数的名字进行参数传递的,关键字可以不遵守位置的对应关系
sub(x = 300, y = 100)
sub(6,y = 4)# 关键字传递,如果不写关键字将按照顺序进行传参,但是顺序需要注意,看下一条.
关键字传参可以和位置传递混用,但位置参数要出现在关键字参数之前.
参数默认值:
定义阶段,参数被预先赋予相应的默认值,称这个参数是默认参数.注意,定义时,默认参数的值的类型必须是不可变类型的,否则会带来很多初学者不好理解的问题.非初学者可以忽略.
def pow(x,y = 2):
return x ** y
调用阶段,可以对有默认值的参数重新赋值,也可以不赋值而使用默认的值.
pow(8) # 只给x传参 y使用默认值
pow(8, 3) # 都重新赋值
包裹传递:
在定义函数阶段,有时候并不知道调用的时候会传递多少个参数(参数个数不确定时用这个).这时候,使用包裹位置参数或者包裹关键字参数,来进行参数传递,会非常有用.
包裹位置参数:
定义阶段,参数的前面加
*
代表使用包裹位置传递 .
def 函数名称(*参数):
pass
函数体比如求n个数的和,函数可以这样写:
def sum(*numbers):
print(numbers) # 输出一下看看是什么.
sum = 0
for e in numbers:
sum += e
return sum
打印输出会看到它是一个元组.
在调用时参数可以有0到多个,比如:
sum(1,2,3)
sum(1,2,3,4,5,6)
包裹关键字传递
定义阶段,参数前加
**
表示使用的是包裹关键字参数.
# 标准格式:
# def 函数名(**参数):
# 函数体
def func1(**data):
print(data)
调用阶段,将所有的参数名和数值以
key=value
的形式传递,双星号后面的参数会收集打包所有的关键字参数,传递给函数,比如:
func1(x=100, y=200, z=300)
执行,能看到打印的data是一个字典.
对于包裹传递,一般都用
*args
,**kwargs
来接收包裹位置和关键字参数,当然可以自己自定义名称.
解包裹
假如有函数:
def func(x, y, z):
return x + y + z
有一个列表和一个元组
list1 = [1, 3, 5]
tuple1 = [2, 4, 6]
如果使用func分别计算列表所有元素的和,以及元组所有元素的和,那么可以在函数调用的时候使用
*
加上一个列表或元组,*
会将列表或元组的每一个元素对应一个位置参数,简单来说就是把它给拆开进行传递,而不是一整个列表或元组作为一个参数.
func(*list1)
func(*tuple1)
也存在对字典的解包裹,使用相同的func函数,然后创建集合.
data= {'x':1, 'y':2, 'z':3}
在调用的时候使用两个星号
**
,它会把字典中的键值对以关键字参数或包裹关键字参数的形式传递给函数.
func(**data) # 等价于func(x=1, y=2, z=3)
总结一句话,加上星号是拆开的状态,没有星号是打包的状态.
变量的作用域
所谓变量的作用域是指变量起作用的代码范围,不同的作用域内同名变量之间互不影响.
这里说一下全局作用域和局部作用域.
定义在模块级别的变量拥有全局作用域
,这个变量被称为全局变量,现阶段可以理解为写在函数外面的变量可以在整个程序范围内被访问即可.
定义在函数中的变量拥有局部作用域
,这个变量称为局部变量,局部变量只能在声明它的函数内部访问.
x = 10
def f1():
print(x)
f1()
def f2():
x = 200
print(x)
f2()
可以看到程序打印的是200.
局部变量对全局变量有屏蔽效果,此时打印的是局部变量x.一般情况下全局作用域是无法使用局部变量的.
来看代码:
def f3():
words = "python"
print("函数内:",words)
f3()
print("函数外:" ,words)
在函数内部使用
global
关键字,就相当于告诉解释器在函数内部使用的变量是函数外的,再次赋值也就不会新创建一个变量了.
x = 100
def func():
global x
x = 1000
print(x)
总结一句话,如果在函数内部仅使用全局变量,不修改它则不用加global,如果要修改它的值要加上global.
lambda表达式
lambda表达式也是一个语法糖,对于很简单的函数没有必要按标准流程定义它,用lambda一句话就可以搞定.
lambda声明函数的一般形式如下:
lambda 参数列表:表达式
.
可以赋值给一个变量.
def sum(num1, num2):
return num1 + num2
# 函数调用
a = 1
b = 2
print(sum(a, b))
# lambda表达式:lambda a,b:a + b
print(lambda a,b:a + b)
sum_lambda = lambda a,b:a +b
print(sum_lambda(a,b))
函数之lambda表达式(内置函数),在用到函数的地方都可以写lambda.
list_old = [11, 22, 33]
result = filter(lambda e : e % 2 == 0, list_old)
for elem in result:
print(elem)
如有错误还望指出