基本概念
数学定义
y=f(x), y是x的函数, x是自变量. y=f(x0, x1 …xn)
python函数:
是由若干语句组成的语句块,函数名称,参数列表构成,它是组织代码的最小单元
完成一定的功能
函数的作用
结构化编程对代码的最基本的封装, 一般按照功能组织一段代码
封装的目的为了复用,减少冗余代码
代码更加简洁美观,可读易懂
函数的分类:
内建函数,如max()
库函数,如math.ceil
自定义函数,使用def关键字定义
函数定义
def 函数名(参数列表):
函数体(代码块)
[return 返回值]
函数名就是标识符,命名要求一样
语句块必须缩进,约定4个空格
函数名就是标识符就是变量python的函数没有return,会返回none
定义中的参数列表称为形式参数,只是一种标识符占位置的
函数的标识符就是指向函数对象
函数调用,函数名后使用小括号,小括号中填入实际实实在在的参数,简称为实参,定义是形参
不定义会报nameERREO
传参方式:
- 位置传参
按照参数定义顺序传入实参 - 关键字
使用形参的名字来传入实参的方式,如果使用了形参,传参顺序就可和定义顺序不同
要求位置参数必须在关键字参数之前传入,位置参数是按照位置对应的
参数缺省值
缺省值也成为默认值, 可以在函数定义是,为形参增加一个缺省值.其作用:
参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值
参数非常多的时候,并不需要用户每次都输入所有的参数,简化函数调用
可变位置参数
在形参使用* 表示该形参是可变位置参数, 可以接受多个实参
它将收集来的实参组织到一个tuple中
tuple 有序按位置传参
可变关键字参数
在形参使用表示该形参是可变关键字参数,可以接受多个关键字参数
它将收集来的实参的名称和值,组织到一个dict中
可变的关键字传参 kwargs
有可变位置参数和可变关键字参数
可变位置参数在形参前使用一个*号
可变关键字参数和可变关键字参数度可以收集若干个实参,可变位置参数收集形成一个tuple
可变关键字参数收集形成一个dict
混合使用参数的时候,普通参数需要放到参数列表前面, 可变参数要放到参数列表的后面
要在可变关键字参数之前.
keyword-only 参数
def fn(args, x, y, **kwargs):
print(x, y, args, kwargs, sep=’\n’, end=’\n\n’)
fn(3, 5)
fn(3, ,5, 7)
在python3之后,新增了keyword-only参数
keyword-only参数:在形参定义时,在一个星号之后, 或一个可变位置参数之后, 出现的普通参数,就已经不是普通的参数了,称为keyword-only参数
keyword-only参数,言下之意就是这个参数必须采取关键字传参
可以认为,args可变位置参数已经截获了所有位置参数, 其后的变量x不可能通过位置传参传入了.星号后所有的普通参数都成了keyword-only参数
参数的混合使用
参数规则:普通参数,缺省参数,可变位置参数,keyword-only参数,可变关键字参数
代码应该易读易懂, 而不是为难别人
请按照书写习惯定义函数参数.
参数解构:
在给函数提供实参的时候,可以在可迭代对象前使用或者来进行的解构,提取出其中所有元素作为函数的实参.
使用*解构成位置参数
使用解构成位置 传参
提取出来的元素数目要和参数的要求匹配
python函数使用return语句返回”返回值”
所有函数都有返回值,如果没有return语句, 隐式调用return None
return语句并不一定是函数的语句块的最后一条语句
一个函数可以存在多个return语句,但是只要一条可以被执行,如果没有一条return语句被执行,隐式调用return None
如果有必要,可以显示调用return None ,可以简写return
如果函数执行了return语句,函数就会返回,当前执行return语句之后的其他语句就不会被执行
返回值的作用: 结束函数调用,返回返回值
函数不能同时返回多个值.
作用域
一个标识符的可见范围,这就是标识符的作用域,一般常说的是常量的作用域
注意:每一个函数都会开辟一个作用域
分类:
全局作用域:
在整个程序运行环境中都可见
全局作用域中的变量称为全局变量
局部作用域:
在函数 ,类等内部可见
局部作用域中的变量称为局部变量,其使用范围不能超过所在其所在局部作用域
函数嵌套
在一个函数中定义了另一个函数
内部函数不能在外部直接使用,会抛NameError异常,因为它在函数外部不可见
global语句
使用global关键字的变量,将声明为外部的全局作用域中定义的
使用了global 不再是局部变量,它是全局变量
global使用原则
外部作用域变量会在内部作用域可见,但也不要在这个内部的局部作用域中直接使用,应为函数的目的就是为了封装,尽量与外界隔离
如果函数需要使用外部全局变量,请使用函数的形参定义,并再调用传实参解决
一句话:不要global,学习他就是深入理解变量作用域
闭包
自由变量:未在本地作用域中定义的变量
闭包: 就是一个概念,出现在嵌套函数中 ,指的是内层函数引到了外层函数的自由变量, 就形成了闭包,很多语言都有这个概念,最熟悉就是javascript
nonlocal语句
将变量标记为不在本地作用域定义, 而是上级的某一级局部作用域中定义, 但不能是全局作用域中定义
内部函数使用nonlocal关键字声明count变量在上级作用域而非本地作用域中定义
代码中内层函数引到外部局部作用域中的自由变量,形成闭包
函数也是对象,每个函数定义被执行后,就生成了一个函数对象和函数名这个标识符关联
python把函数的默认值放在函数对象的属性中,这个属性就伴随着这个函数对象的整个生命周期
查看default属性,他是个元组
变量名解析原则LEGB***
local,本地作用域,局部作用域的local命名空间,函数调用时创建,调用结束消亡
Enclosing,python引入了嵌套函数,实现了闭包,这个就是嵌套函数的外部函数的命名空间
global 全局作用域,即一个模块的命名空间 模块被import时创建,解释器退出时消亡
build-in,内置模块的命名空间,生命周期从python解释器启动时创建到解释器退出时消亡
所以一个名词的查找顺序就是LEGB.
|