Python学习笔记
61-函数
for i in range(1, 10):
print(i)
print('*********************')
def test():
for i in range(1, 10):
print(i)
print('*********************')
test() # 函数调用
"""
使用函数的优点:
1.简化代码结构
2.提高代码的复用性
3.提高代码的可读性和可维护性
"""
62-函数调用
'''
注意:
1.函数定义完之后,并不会直接输出,需要调用才会输出
2.函数名若赋给了一个变量,那该变量就具备了和函数一样的功能,可以像函数一样调用。
3.函数必须先定义,才能调用,函数调用的位置必须放在函数定义之后.
4.若在同一个文件中,出现了相同名字的函数,后面的函数会覆盖前面的函数,
5.函数可以多次调用,调用次数和调用位置无关。
'''
def demo():
print('你好呀Python')
demo() #调用函数
test = demo #将函数赋值给一个变量
test() #调用函数
63-函数分类
'''
函数分类
1.内置函数
2.自定义函数
3.有参数的函数
4.无参数的函数
5.有名字的函数
6.匿名函数
7.有返回值的函数
8.无返回值的函数
'''
print('内置函数')
def test():
print('自定义函数')
test() #调用函数
def test_1(a,b):
print('有参数的函数', a+b)
test_1(1,2) #调用函数
def test_2():
print('无参数的函数')
test_2() #调用函数
def test_3():
name = '有返回值的函数'
return name
print(test_3()) #调用函数
def test_4():
print('无返回值的函数')
test_4() #调用函数
64-函数嵌套
def add():
print("add")
def sub():
add() # 嵌套函数
print("sub")
sub() # 函数调用
65-函数中的参数
# 封装一个函数,传入两个数字,输出两个数字较大的值
def max_num(num1, num2):
if num1 > num2:
print('较大的数字',num1)
return num1
else:
print('较大的数字',num2)
return num2
max_num(10,20)
'''
1.在函数定义时,传入的参数叫做形式参数,也叫形参。 num1 和 num2
2.函数调用时,传入的参数叫做实际参数,也叫实参。10和20
3.传参指的是函数调用的时候,传入的实际参数会替换形式参数,
4.一般情况下,形参的数量和实参的数量保持一致.
5.在函数中,形参的名字和实参的名字可以一致,(本质上是开辟了两块不同的空间)
'''
66-函数中的参数类型
'''
必须参数:
调用函数的时候,必须以正确的顺序传参,实参的数量和形参的数量保持一致
'''
def demo(name, age):
print('姓名:%s,年龄:%d'%(name, age)) # %s格式化字符串,%d格式化整数
demo('张三', 18) # 正确
# demo(18, '张三') # 若参数顺序错误,报错
'''
关键字参数:
允许函数调用的时候,实际参数和形式参数的顺序不一致,使用关键字进行白动匹配
'''
demo(age=24, name='张三') # 正确
'''
默认参数:是指在函数定义时,给形参设置的默认值
'''
def func(num_1, num_2=10): # num_2=10为默认参数
print(num_1 + num_2)
func(10) # 20
func(20, 20) # 40
'''
使用默认参数时,注意的事项:
1.若函数中有默认参数,在调用函数时,若没有传递参数,则使用默认参数,若传递了参数,则使用传递的参数,传递的参数会覆盖默认参数.
2.在定义函数时,若有默认参数,默认参数要放在参数列表的最后面.若放在前面会报错.
'''
# def func(num_1=10, num_2): # 报错
# print(num_1 + num_2)
'''
不定长参数(可变参数):*args和**kwargs
*args:用来接受多个位置参数,args是arguments的简写.得到的参数是一个元组.
**kwargs:用来接受多个关键字参数。kwargs是 keyword arguments的简写,得到的参数一个字典.
'''
def f(num,*args):
print(num,args)
f(1) # 1 ()
f(1,2) # 1 (2,)
func(1,2,3) # 1 (2, 3)
# 注意:若函数参数中有*args和普通参数,要把可变参数(*args)放在参数列表的最后面.
# def f(*args,num): # 报错
# print(args,num)
def f_2(num,**kwargs):
print(num,kwargs)
f_2(1, x=2,y=3) # 1 {'x': 2, 'y': 3}
'''
1.若函数中有**kwargs参数,在传输kwargs参数时,必须有键值对形式传输,k=v这种形式
2.参数列表中的**kwargs必须放在参数列表的最后面.
'''
# def f_2(**kwargs,num): # 报错
# print(kwargs,num)
67-函数中的返回值
def demo():
print("燕雀安知鸿鹄之志哉")
demo()
def ret(a, b):
sum = a + b
return sum
print(ret(1, 2)) # 3
def test():
name = "小明"
age = 18
sex = "男"
return name, age, sex
print(test()) # ('小明', 18, '男')
def test_2():
name = "小明"
age = 22
sex = "男"
return name, age, sex
print("hello")
print(test_2()) # ('小明', 22, '男')
def test_3():
name = "小明"
return
print(test_3()) # None
'''
1.函数中若需要将某些数据返回,使用关键字return.
2.函数中通过return返回的结果,返回到了函数调用的位置
3.函数中的return可以一次性返回多个数据,返回的数据以元组的形式保存
4.函数中若出现了return,return后面的程序不会执行,
5.函数中若出现了return,但是return后面没有返回任何数据,仅仅表示结束程序,默认返回的是None
'''
68-匿名函数
# 有名函数
def add(a):
return a ** 2
print(add(2)) # 4
# 匿名函数
demo = lambda a: a ** 2
print(demo(2)) # 4
print((lambda a: a ** 2)(2)) # 4
'''
匿名函数的特点:
1.lambda只是一个表达式,比普通函数简单,逻辑清晰
2.lambda表达式一般只会书写一行,包含了参数 函数体和返回值
3.lambda表达式调用时,一般使用变量接收,然后通过变量调用该函数
'''
# 使用匿名函数计算传入的两个数字的乘积
test = lambda a, b: a * b
print(test(2, 3)) # 6
print((lambda a, b: a * b)(2, 3)) # 6
69-回调函数
def demo(a,b):
print(a + b)
demo(1,2) # 3
num = demo
num(3,4) # 7
# 若把函数名赋给了一个变量,那该变量也具备了函数的功能
# 回调函数:把一个函数(a)作为一个参数传递到另外一个函数(b)中去,那么函数a就是回调函数
# 加法
def add(a,b):
print(a + b)
# 减法
def sub(a,b):
print(a - b)
# 乘法
def mul(a,b):
print(a * b)
# 除法
def div(a,b):
print(a / b)
add(12,4) # 16
sub(12,4) # 8
mul(12,4) # 48
div(12,4) # 3.0
# 封装一个函数:该函数可以实现加减乘除4种运算
def calc(a,b,func):
func(a,b)
# 加法
calc(12,4,add) # 16
# 减法
calc(12,4,sub) # 8
# 乘法
calc(12,4,mul) # 48
# 除法
calc(12,4,div) # 3.0
70-闭包
# 如果一个函数内部定义了另外一个函数,那么外边的函数叫做外函数,内部的函数叫做内函数
# 如果在一个外部函数中定义了一个内部函数,并且外部函数的返回值是内部函数,这就构成了一个闭包,内部函数被称为闭包函数.
'''
闭包函数成立的条件:
1.函数嵌套函数
2.内部函数引用外部函数的变量
3.外部函数返回内部兩数.
'''
# 最简单的闭包函数(不严谨)
def outer(): # 外部函数
def inner(): # 内部函数
print('内部函数执行了')
return inner # 外部函数返回内部函数
func = outer() # outer函数执行了,返回inner函数
func() # inner函数执行了
# 内部函数使用外部函数的变量
def outer_1(x): # 外部函数
num = 10
def inner_1(): # 内部函数
print(num + x) # 内部函数使用外部函数的变量
return inner_1 # 外部函数返回内部函数
func_1 = outer_1(20) # func_1 = inner_1
func_1() # inner_1()
# 应用场景:闭包主要应用于装饰器
71-装饰器
def test_1():
print('test_1')
test_1()
# 需求:向test()函数中,新增一个功能,多输出一句话"给他补铁!
# 第一种方法,重写函数
def test_2():
print('第一种方法,重写函数,test_1')
print('给他补铁')
test_2()
# 第二种方法,函数嵌套函数
def test_3():
test_1() # 调用test_1
print('第二种方法,函数嵌套函数,给他补铁')
test_3()
'''
装饰器:在代码运行期间,可以动态的给原函数新增功能,被称为装饰器,(使用闭包函数实现)
使用装饰器的好处:
在团队开发中,假如两个或两个以上的同事使用了相同的功能,但是功能上面有一些细微的差别,这时候可以采用装饰器的方式进行调整.互相不影响,代码简化.
'''
def outer(func): # func表示形参,调用的时候实参会替换形参
def inner():
func() # 调用原函数(print('test_1'))
print('这是inner函数') # 新增的功能
return inner
# 普通装饰器函数的方式
test_1 = outer(test_1)
test_1()
# 简写方式:在使用简写方式的时候,原函数必须写在装饰器的下面
@outer # test_4 = outer(test_4)
def test_4():
print('这是test_4函数')
test_4()
72-装饰器传入不走长参数
# 需求:给下面的四个函数新增一句话:"数学运算的结果是:"
# 定义装饰器函数
def common(func):
def wrapper(*args): # *args 代表可变参数
print("数学运算的结果是:", end="")
func(*args)
return wrapper
# 加法
@common
def add(a,b):
print(a + b)
# 减法
@common
def sub(a,b,c):
print(a - b - c)
# 乘法
@common
def mul(a,b,c,d):
print(a * b * c * d)
# 除法
@common
def div(a):
print(1/a)
add(12,4) # 16
sub(12,4,3) # 5
mul(12,4,3,2) # 288
div(12) # 0.08333333333333333
73-多个装饰器修饰同一个函数
# 需求:在原函数 test()的基础上新增两个功能,权限验证和查看日志
def outer_1(func):
def inner_1():
print("权限验证")
func()
return inner_1
def outer_2(func):
def inner_2():
print("查看日志")
func()
return inner_2
@outer_1 # 调用outer_1装饰器
@outer_2 # 调用outer_2装饰器
def tset():
print("测试函数")
tset()
'''
注意:
1.当多个装饰器修饰同一个函数时,按照原函数和新增的功能的顺序从上往下执行
2.不管几个装饰器函数修饰原函数,原函数只会调用一次.
'''
74-作用域
# 变星的作用域:是指变量能够被访问的范围.
# 程序中的变量不是在任意位置都可以直接被访问的,访问的权限取决于变量的位置
if 5 > 3:
x = 5
print(x)
for i in range(5):
b = 8
print(b)
# 在Python中,分支语句1f,if...else...,和循环中定义的变量,在外部可以直接访问,不存在作用域的问题。
'''
作用域的分类
局部作用域
函数作用域
全局作用域
内建作用域
'''
# 局部作用域
def f():
x = 5
print(x)
f()
# 全局作用域
# 函数作用域
def outer():
x = 5
def inner():
print(x)
return inner()
asdf = outer()
asdf()
# 内建作用域
nn = int('123')
print(nn)
75-global和nonlocal介绍
num = 1
def f():
num = 2
print(num)
print(num) # 1
f() # 2
print(num) # 1
'''
1.当函数内部出现了和函数外部名字一样的变量,在函数中使用函数内部的变量。
2.在函数内部定义了和函数外部名字一样的变量,不会修改函数外部变量的值.
'''
# 1.若想在函数的内部修改函数外部变量的值,使用global关键字
n = 1
def func():
global n # global关键字
n = 2
print(n)
func() # 2
print(n) # 2
# 2.nonlocal:主要用于闭包函数中
def outer():
x = 1
def inner():
nonlocal x # nonlocal关键字,在内部函数中想要修改外部函数中的变量时
x += 1
print(x)
return inner
oo = outer() # outer函数
oo() # inner函数
76-递归函数
# 递归函数:函数自己调用自己
# 需求:使用函数的方式,计算数字n的阶乘
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)
print(factorial(5))
# 封装函数,使用递归实现传入一个数字m,得到第m个斐波拉契数列的数字
# 斐波拉契数列前两个数字是1,从第三个数字开始,后面的数字是前面的两个数字的和
def fib(n):
if n <= 2:
return 1
else:
return fib(n - 1) + fib(n - 2)
print(fib(8))