python函数
函数的优点:
- 代码可复用
- 代码可维护性高
- 容易排错
- 可读性好
- 利于团队开发
函数就是完成特定功能的代码块,本质上是对代码的封装。 语法格式
函数名命名规则同变量量名,要满足标识符命名规则
def 函数名([参数1],[参数2]....[参数n]):
函数体
- 不能和系统函数重名,否则系统函数无法使用
- 函数定义分两部分函数头和函数体
- 函数体,就是实现功能的代码段,以:开头,必须缩进
- 函数名的命名风格:一般建议用下划线分隔的小写单词组成:say_hello
函数参数
实参和形参
- 形参:就是函数定义时,小括号里的变量
形参顺序须按照以下顺序:位置参数、默认值参数、*args,**kwargs
形参顺序须按照以下顺序:位置参数、默认值参数、*args,**kwargs - 实参:函数调用的时候,小括号里的变量
- 位置参数,要求实参顺序必须和形参顺序完全一致,由形参顺序决定实参顺序
- 关键字参数,函数调用时,实参可以是键值对,键就是形参名字,这样的调
用,实参不必关心形参的顺序。默认值,如果形参在定义的时候给定一个值,那么函数在调用时就可以不传实参,可以简化调用- 默认值参数必须放到最右边
如果传了实参,那么实参优先,不会使用默认值
默认值只计算一次
默认值必须是不可变对象
- 默认值参数必须放到最右边
函数可以没有形参和实参
可以通过return语句句返回计算结果。语法: return 表达式
- return的作用一个是终止函数的执行,所有执行了return后,其后的语句不会被执行
如果没有return语句,则默认返回的是None - return还可以返回给调用者数值
return可以返回一个值,如果要返回多个值,那么返回的是一个元组
函数类型
- 自定义函数
- 匿名函数
不再使用def 函数名()这种形式定义函数,而是使用lambda来创建匿名函数
add = lambda a,b:a + b - 传入函数
一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数,也可以称
之为传入函数。可以实现通用编程,排序等复杂功能
# 通用求和函数
def sum1(n, callback):
"""
功能:求满足callback规定条件的数的和
:param n: 大于0的整数
:param callback: 用于判断一个数是否满足指定条件,由调用者传入,有一个参数,形如:def callback(n)
:return: 求和的结果
"""
sum = 0
for i in range(1, n + 1):
if callback(i):
sum += i
return sum
print(sum1(100, lambda x: x % 2 == 0))
print(sum1(100, lambda x: x % 7 == 0))
print(sum1(100, lambda x: x % 15 == 0 and x % 7 != 0))
- 闭包函数
我们可以在一个函数中再定义一个函数,在函数内部定义的函数称之为内部函数,内部函数只能在函数内使用,不会污染外部空间。定义内部函数的函数称之为外部函数,这样的定义构成函数的嵌套
def outter(a): #外部函数
x = a
def inner(y): #内部函数
# nonlocal关键字声明一下x,表示这个变量不是局部变量,需要向上一层变量空间找这个变量。
nonlocal x
x += 10
return x + y #引⽤用外部变量量
return inner #返回内部函数(闭包)
- 偏函数
当一个函数有大量参数,调用的时候非常不方便,可以使用偏函数技术,将一些参数固定(给默认值),达到简化函数调用的目的。
import functools
def test(a,b,c,d):
print(a, b, c, d)
#从前面固定参数,使用位置参数就行,1=>a,2=>b
test1 = functools.partial(test,1,2)
test1(3,4) #3=>c 4=>d
#从后面固定参数,需要使用关键字参数
test2 = functools.partial(test,c=3,d=4)
test2(1,2) #1=>a 2=>b
#如果固定的参数不连续,则需使用关键字参数固定
test3 = functools.partial(test,b=2,d=4)
test3(a=1,c=3) #需要使用关键字参数,否则会报错
函数的作用域
程序中的变量并不是在任意的位置都可以随意访问,在哪里可以访问取决于这个变量的作用域,变量的作用域指的是变量在那段代码中可以使用,可以使用变量的那段代码就是变量的作用域。在python中,只有函数/类/模块才引入作用域,if/elif/else , while/for,try/except等并不会引入新的作用域
- 按照作用域划分,可以分为:
L:Local,局部作用域
E:Enclosing,闭包作用域【闭包的外部函数中定义的变量】
G:Global,全局作用域 在所有函数外定义的变量
B:Built-in,內建作用域【内置作用域】
以 L --> E --> G -->B 的规则查找,即:在局部找不到,便会去局部外的局部找(例
如闭包),再找不到就会去全局找,最后到内建作用域中找。
定义在函数内部的变量拥有一个局部作用域,被称为局部变量
定义在函数外面的变量拥有一个全局作用域,被称为全局变量
局部变量和全局变量同名,局部优先
一般情况下,如果一个函数结束,函数的内部所有东西都会释放掉,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的局部变量将来会在内部函数中用到,就把这个局部变量绑定给了内部函数,然后自己再结束。