函数,修饰器
函数
1. 函数的定义
1 | def print_ok(): # 函数的定义格式 |
函数的返回值如果没有指定,则系统自动返回none
2. 函数的参数
必须参数: 按照定义的时候的参数的顺序传入
1
2
3
4
5
6
7
8
9
10
11
12def add(a, b): # 定义两个参数
print("%d+%d=%d" % (a, b, a+b)) # 函数中的格式化字符串,执行语句
st = "{a}+{b}={result}"
st = st.format(a=a, b=b, result=a+b) # 复习字符串的格式化
print(st)
return True
add(1, 2) #调用函数
# 执行结果:
1+2=3
1+2=3关键字参数:
1
2
3
4
5
6
7
8
9
10
11
12def print_info(name, age): # 定义一个打印信息的函数
print('name:%s' % (name,))
print('age:%d' % (age,))
print_info('海涛', 18) # 调用函数
print('分隔'.center(50, '-')) # 字符串的方法,分隔两次调用
print_info(age=19, name='涛哥' ) # 关键字传入参数,可以不按照顺序。
# 执行结果:
name:海涛
age:18
------------------------分隔------------------------
name:涛哥
age:19默认参数:在定义的时候定义:
1
2
3
4
5
6
7
8
9def print_info(name, age, sex='male'): # 默认参数,定义时默认的参数必须在最后
print("name:%s,age:%d,sex:%s" % (name, age, sex,))
print_info('海涛', 18, ) # 调用,打印默认的值
print_info('海涛', 18, sex='female') # 调用,给默认值赋值,覆盖原有的值
print_info('海涛', 18, 'female') #另一种方法
# 执行结果:
name:海涛,age:18,sex:male
name:海涛,age:18,sex:female
name:海涛,age:18,sex:female不定长参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25# 第一种不定长参数
def add(*args): # 定义不定长参数,加一个*符号:将传入的参数做成一个元组
print(type(args)) # 打印传入的内容的类型
my_sum = 0
for i in args:
my_sum += i
print(my_sum)
add(1, 2, 3, 4) # 传入四个数字,当然也可以传入多个数字
# 执行结果:
<class 'tuple'>
10
-----------------------------------------------------------------
# 第二种不定长参数
def print_info(**kwargs): # 加两个**符号:将传入的参数做成一个字典
print(type(kwargs)) # 打印传入的参数的类型
for k, v in kwargs.items():
print(k, ':', v)
print_info(name="海涛", height=180, ishandsome=True)
# 执行结果:
<class 'dict'>
name : 海涛
height : 180
ishandsome : True以函数为参数(高阶函数)
1
2
3
4
5
6
7
8
9def f(n): # 这个函数,求n的平方
return n*n
def foo(a, b, func): # 函数名作为参数
c = func(a) + func(b)
return c
print(foo(1, 2, f))
# 执行结果:5
二. 修饰器
1. 预备知识
作用域:我们在某一个函数内引用一个变量时,系统如何在代码中查找变量呢?
查找顺序:L_E_G_B,如下
1
2
3
4
5
6 a = 10 #G
def func():
b = 9 #E
def abc(): # 函数中的内部函数,
c = 8 #L
return 1
高阶函数,:1.函数可以作为函数的参数传入,2. 函数可以作为返回值返回,3. 闭包的概念
- 闭包的概念:闭包定义:如果在一个内部函数里面,对在外面的作用域(但不是全局作用域)的变量进行引用,那么内部函数被认为是闭包。
- 闭包的例子:
1
2
3
4
5
6
7
8
9
10
11
12 def outer():
x = 10
def inner(): # 内嵌函数 #条件一:是内部函数
print(x) # 条件二:对外部变量引用
return inner # 结论:是一个闭包
outer()() # 调用inner
f = outer()
f() # 调用inner,可以拿到x的值,说是闭包
# 执行结果:10 10
2. 修饰器
开发封闭原则,对修改封闭,对扩展开放。
就是,写好一个方法以后就不让修改了,但是还保留扩展的特性
修饰函数,重新写一个函数,可以在这个函数中写一个内嵌函数,内嵌函数中可以对原有的函数进行扩展,然后返回这个内嵌函数。这个函数就是修饰函数,
然后通过特定的格式,把实现了新功能的函数赋给原函数
例如有一个函数foo(),现在要拓展它的功能,在执行完该函数后打印该函数执行的时间,但是不要修改foo()内部以及函数名
- 实现如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import time
def show_time(func): #装饰函数
def inner():
start = time.time()
func() # 在内嵌函数中调用传入的函数,实现原来的功能
end = time.time()
print(end - start)
return inner # 返回这个内嵌函数
def foo(): # 原来的foo函数,
print("foo......")
time.sleep(1)
foo() # 函数的执行调用
原来的函数有参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16def show_time(func):
def inner(*x): # 在内嵌函数中传入一个不定长参数,
start = time.time()
func(*x) # 将该不定长参数给原来的函数
time.sleep(1)
end = time.time()
print(end-start)
return inner # 返回内嵌函数
def add(a, b):
sum = a + b
print(sum)
add(1, 2)修饰函数设置开关:
比如我想将一些内容打印到日志中,可以使用以下方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19def logger(flag): # 在最外边加一个函数
def show_time(func):
def inner(*x):
start = time.time()
func(*x)
time.sleep(1)
end = time.time()
print(end-start)
if flag == 'true':
print("日至记录")
return inner
return show_time
def add(a, b):
sum = a + b
print(sum)
add(1,2)