函数
简介
函数是一个程序语言的基本功能,函数主要用来封装一个代码块,从而对部分的代码进行封装。
定义函数
定义一个函数需要使用def关键字,依次写出函数名、参数列表、函数体、return返回语句
def 函数名(参数列表):
函数体
定义一个函数:
def func_abs(x):
if x >= 0:
return x
else:
return -x
调用函数
f = func_abs(-10)
print(f) # 10
函数的参数
- 必备参数
- 关键字参数
- 默认参数
- 不定长参数
必备参数
必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样
def print_info(info):
print(info)
print_info('输出信息')
关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。 使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
def print_info(info1, info2):
print(info1, info2)
print_info(info2='信息二', info1='信息一')
默认参数
用函数时,如果没有传递参数,则会使用默认参数。
def print_info(name, age=20):
print(name, age)
print_info('Tom', 10)
print_info('Jake')
不定长参数
加了星号”“的变量args会存放所有未命名的变量参数,args为元组 ;而加”*“的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典。
def print_info(name, *args, **kwargs):
print(name, args, kwargs)
print_info('Tom', '篮球', '足球', '乒乓球', age=20, height=170, address='beijing')
装包与拆包
- args和kwargs:*args和 **kwargs是在python的代码中经常用到的两个参数,初学者对这两个参数的理解可能仅仅限于*args是用于接收多余的未命名参数,**kwargs用于接收形参中的命名参数,其中args是一个元组类型,而kwargs是一个字典类型的数据 。
- 装包:装包的意义就是把未命名的参数和命名的参数放在元组或字典中。
- 拆包:
- 解包的意义就是将传递给函数的一个列表、元组、字典拆分成独立的多个元素然后赋值给函数中的参变量。
- 解压字典有两种解发,一种用*解的只有key,一种用**解的有key,value。但是这个方法**只能在函数定义中使用。
def func1(*args):
print(type(args)) # <class 'tuple'>
print(args) # 未拆包:(1, 2, 3, 4)
print(*args) # 拆包:1 2 3 4
func1(1, 2, 3, 4) # 装包
def func2(**kwargs):
print(type(kwargs)) # <class 'dict'>
print(kwargs) # 未拆包:{'name': '小明', 'age': 20, 'height': 170, 'address': 'beijing'}
print(*kwargs) # 拆包,只输出key:name age height address
for k, v in kwargs.items():
print(k, v)
func2(name='小明', age=20, height=170, address='beijing') # 装包
变量作用域 (LEGB)
变量作用域
- L (Local) 局部作用域
- E (Enclosing) 函数范围作用域(闭包函数外的函数中)
- G (Global) 全局作用域
- B (Built-in) 内建作用域
在python中,每个变量都会有其生存的作用域,一般的查找变量的时候以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找,如果再没有,那么就会出现报错异常。
b = int(2.9) # 内建作用域(内置方法属性)
g = 0 # 全局作用域
def outer():
e = 1 # 闭包函数外的函数中
def inner():
l = 2 # 局部作用域
total = 0
def sum(arg1, arg2):
total = arg1 + arg2
print('局部变量:%d' % total) # 局部变量:30
sum(10, 20)
print('全局变量:%d' % total) #全局变量:0
当内部作用域想修改外部作用域的变量时,就要用到==global==和==nonlocal==关键字了
total = 0
def sum(arg1, arg2):
global total
total = arg1 + arg2
print('total:%d' % total) # total:30
sum(10, 20)
print('total:%d' % total) # total:30
def outer():
num = 10
def inner():
nonlocal num
num = 100
print(num) # 100
inner()
print(num) # 100
outer()
lambda 函数
lambda函数是一个匿名函数,使用lambda关键字,函数体比 def 简单很多。
lambda函数是匿名的:所谓匿名函数,通俗地说就是没有名字的函数。lambda函数没有名字。
lambda函数有输入和输出:输入是传入到参数列表argument_list的值,输出是根据表达式expression计算得到的值。
lambda函数一般功能简单:单行expression决定了lambda函数不可能完成复杂的逻辑,只能完成非常简单的功能。由于其实现的功能一目了然,甚至不需要专门的名字来说明。
语法: lambda 函数的语法:
lambda [arg1 [,arg2,.....argn]]:expression
案例
# 函数传递
def func(a, b, opt):
print('result=%d' % opt(a, b))
func(11, 22, lambda x, y: x + y)
# 排序
sample_list = [{'name': 'Tom'},
{'name': 'Jake'},
{'name': '小明'}]
sample_list.sort(key=lambda x: x['name'])
print(sample_list) # [{'name': 'Jake'}, {'name': 'Tom'}, {'name': '小明'}]
递归函数
一个函数在内部调用自身本身,这个函数就是递归函数
不使用用递归
# 1*2*3*4*5
def calculate_num(num):
result = 1
for i in range(1, num + 1):
result *= i
return result
result = calculate_num(5)
print(result) # 120
使用递归相乘
# 1*2*3*4*5
def calculate_num(num):
if num > 1:
return num * calculate_num(num - 1)
else:
return 1
result = calculate_num(5)
print(result) # 120
打印1~100
def print_num(start, end):
if start <= end:
print(start)
print_num(start + 1, end)
print_num(1, 100)