函数文字定义: 函数是组织好的, 可重复使用的, 用来实现单一, 或相关联功能的代码段; 函数能提高应用的模块性, 和代码的重复利用率.
定义函数
函数的定义有以下规则:
函数代码块以 def 关键词开头, 后接函数标识符名称和圆括号 ().
任何传入参数和自变量必须放在圆括号之中, 圆括号之中可以用于定义参数.
函数内容以冒号起始, 并且缩进.
return [表达式] 结束函数, 选择性地返回一个值给调用方. 不带表达式的 return 相当于返回 None.
定义语法
def 函数名(参数):
函数体
示例
- # 输出 hello world 函数
- def HelloWorld():
- print('Hello world')
- # 函数调用
- HelloWorld()
几种参数的用法
1, 默认参数
在函数调用时, 可以不传送值的参数; 或者说, 有默认值的参数
默认参数的值可以被覆盖
默认参数必须在参数列表的最后
默认参数在函数里只分配一次
- 示例:
- # 例 1:
- #!/usr/bin/python3
- import random
- def choose_num(s,e=10):
- num = random.randint(s,e)
- return num
- choose_num(3) # 调用时只传了 s, 未传 e,e 用的默认值
输出 5
choose_num(1,50) # 默认值被覆盖
输出 28
- # 示例 2, 默认值必须在最后
- #!/usr/bin/python3
- def choose_num(s=10,e): # 默认值放前边, 报错了.
- num = random.randint(s,e)
- return num
- choose_num(3)
报错
- File "<ipython-input-18-16c067f4bcb8>", line 1
- def choose_num(s=10,e):
- ^
- SyntaxError: non-default argument follows default argument
- def choose_num(s, e=10, n=5):
- numbers = []
- for x in range(n):
- num = random.randint(s,e)
- numbers.append(num)
- return numbers
- choose_num(3)
输出
- [6, 7, 4, 3, 8]
- # 示例 3, 默认值只分配一次
- #!/usr/bin/python3
- def f(a,L=[]): # 由于默认值只在内存里分配一次, 所以当此列表做默认值时,
- L.append(a) # 结果不管调用多少次, 都是往已经分配好的列表中追加的
- return L # 就是结果中的样子.
- # 而不是第一次返回 [1] 第二次返回[2] 第三次返回[3]
- print(f(1))
- print(f(2))
- print(f(3))
输出
- [1]
- [1, 2]
- [1, 2, 3]
2, 关键参数(k=v 方式给参数传值)
示例代码:
- #!/usr/bin/python3
- def car(color,price='10',user='yhyang'):
- print(f'{user}有一辆 {color} 色的车, 价值 {price} 块')
- car('蓝') # 其它的使用默认参数
- car('红','30','hmm') # 对应位置覆盖
- car(color='blue',price='100',) # k=v 的方式给参数传值,
输出
yhyang 有一辆蓝色的车, 价值 10 块
hmm 有一辆红色的车, 价值 30 块
yhyang 有一辆 blue 色的车, 价值 100 块
3, 任意参数
用 *args , **kwargs 作参数, args->tuple,kwargs->dict
示例代码:
- #!/usr/bin/python3
- def car(*args): # 一个 * 号跟 args, 即 *args 可以成为一个元组
- print(args) # 两个 * 号跟 kwargs 即 **kwargs 可以成为一个字典
- for k in args: # 重点在于 * 号有几个, 不在于 args kwargs 的名称
- print(k)
- car("red",10,"yhyang")
输出
- ('red', 10, 'yhyang')
- red
- 10
- yhyang
- #!/usr/bin/python3
- def car(**kw): # 这种参数, 在传递的时候需要传递 key=value 的方式, 才能按字典的方式存储并打印
- for k,v in kw.items():
- print(f'{k}::{v}')
- car(color='red',price=20,user='yhyang')
输出
- color::red
- price::20
- user::yhyang
- #!/usr/bin/python3
- def car(*args,**kw): # 可以识别单个参数和 key value 参数
- print('args:',args)
- print('kw:',kw)
- for k in args:
- print(k)
- for k,v in kw.items():
- print(f'{k}::{v}')
- car('adfsdf','t',color='red',price=20,user='yhyang') # 可以识别单个参数和 key value 参数
输出
- args: ('adfsdf', 't')
- kw: {'color': 'red', 'price': 20, 'user': 'yhyang'}
- adfsdf
- t
- color::red
- price::20
- user::yhyang
4, 注意: 直接传字典名字的时候要加两个 * 号
示例代码:
- #!/usr/bin/python3
- kwargs = {'color':'red','price':30,}
- def car(**kw):
- print(kw)
- car(**kwargs) #这里注意, 传字典名字的时候前面要加两个 *
输出
{'color': 'red', 'price': 30}
5, 下面这种写法,* 参数可传可不传, 但是 price 一定要传, 而且是以 key value 的方式来传
示例代码:
- #!/usr/bin/python3
- def car(color='blue',*,price):
- print(color,price)
- car(price=30)
输出
blue 30
函数注释与文档说明(annotations,doc)
示例代码:
- #!/usr/bin/python3
- def add(x,y):
- """Add x and y together.""" # 函数文档说明, 写在函数定义的第一行, 就可以用
- return x+y # 函数名.__doc__来查看函数说明文档
- add.__doc__
- 输出
- 'Add x and y together.'
- 下边例子中, x:int y:'这个参数随便' 是对 x 和 y 的说明 ;-> int 是对函数返回值的说明, 在执行过程中, 会将这个说明忽略
- doc 来获取函数说明文档, annotations 来获取函数参数及返回值
- 示例代码:
- #!/usr/bin/python3
- def add(x:int, y:'这个参数随便')-> int:
- """Add x and y together."""
- return x+y
- add.__doc__
- add.__annotations__
输出
- 'Add x and y together.'
- {'x': int, 'y': '这个参数随便', 'return': int}
函数变量的作用域
变量作用域, 在自己屋干自己的事儿
本地(局部)
封闭
全局
内置
示例代码:
- # 以下代码会报错
- #!/usr/bin/python3
- x = 1 # 全局
- def add():
- x += 1 # 局部变量赋值错误, 此处 x 没有被声明, 所以不能被赋值, 此处 x 不是全局的 x
- print(x)
- add()
- error_list = [2,3,5]
- def big_list():
- error_list += [99] # 此处是 error_list = error_list + [99], 需要先在函数内部声明 error_list, 才不会报错
- print(error_list)
- big_list()
示例代码:
- #!/usr/bin/python3
- error_list = [2,3,5]
- def big_list():
- error_list.append(88) # 此处是在全局变量的基础上追加, 所以可以.
- print(error_list)
- big_list()
输出
- [2, 3, 5, 88]
- error_list = [2,3,5]
- def big_list():
- error_list = [] # 事先声明才能做下边的 += 操作
- error_list += [99]
- print(error_list)
- big_list()
输出
[99]
函数嵌套
函数是 python 里面的一级对象, 可以用在任何地方, 函数里的作用域属于封闭作用域
一级对象
在运行时创建
能赋值给变量或数据结构
作为参数传递给函数
能作为函数的返回结果
示例代码:
- # 函数嵌套
- #!/usr/bin/python3
- def calc(x,y):
- def add(x,y):
- print('x+y:',x+y)
- def sub(x,y):
- print('x-y:',x-y)
- def mul(x,y):
- print('x*y:',x*y)
- add(x,y) # 在函数内部直接执行嵌套的函数
- sub(x,y)
- calc(2,5)
输出
- x+y: 7
- x-y: -3
- # 返回值为函数本身
- #!/usr/bin/python3
- def calc(x,y):
- def add(x,y):
- print('x+y:',x+y)
- def sub(x,y):
- print('x-y:',x-y)
- def mul(x,y):
- print('x*y:',x*y)
- add(x,y) # 在函数内部直接执行嵌套的函数
- sub(x,y)
- return mul # 返回 mul 函数本身, 可以赋给变量
- calc(3,5)
输出
- x+y: 8
- x-y: -2
- <function __main__.calc.<locals>.mul(x, y)>
- c = calc(3,5) # c 被赋值为 mul 函数
输出
x+y: 8
x-y: -2
闭包
函数返回值为内部函数的名字, 内部函数又处理外层函数变量; 这个整体叫闭包
示例代码:
- # 闭包
- #!/usr/bin//python3
- def hello():
- s = 'yhyang' # s 变量在函数中是自由变量
- def say():
- print(s)
- return say # 返回内部函数名, 内部函数绑定了外层函数的变量
- hello()
- h = hello()
- h() # h 得到的值为 say()函数, 再次执行, 则会用到外层函数的变量 s
输出
- <function __main__.hello.<locals>.say()>
- yhyang
函数闭包, 或者闭包函数, 本质是一种函数, 可以在函数运行以后, 依然存在自由变量(或者说可用变量), 可以对闭包的数据进行隐藏, 避免使用全局变量
如上边 hello 中的变量 s 一样, 在第一次执行 h = hello 的时候, 隐藏了 s, 此时 s 为自由变量, 依然存在, 可以继续使用.
来源: http://www.bubuko.com/infodetail-2662130.html