目录
函数
Python语法:
函数的参数:
不定长参数:
参数的解包:
传字典:
返回值:
函数的帮助文档:
作用域:
参数传递:
命名空间:
递归:
高阶函数:
内置高阶函数:
filter函数:
sorted函数:
Lambda表达式:
闭包:
装饰器:
函数
函数是一段可执行的代码,在python中,他也是一种对象,也是一段数据,被保存在内存中
在需要的时候会被取出来执行,多次调用。
函数在python中是一等对象
对象的特点:
1.对象在运行时创建
2.能够赋值给变量或者作为数据结构中的元素
3.能够作为参数传递
4.能够作为返回值使用
Python语法:
def 函数名(形参1,形参2,……,形参n):
函数体
def 函数名(形参1,形参2,……,形参n):
函数体
函数名称命名:规则一般是字母+下划线/驼峰法则
def sayHello():
print('hello')
print(sayHello,type(sayHello))
函数的参数
形参(形式参数)
实参(实际参数)
函数调用的时候,实际参数的数量要和定义的形参数量一致
如果不强调,位置也一样。
位置可以通过名字来强调
def add(a,b):
a += 10
print(a+b)
a = 10
b = 20
add(a,b)#40
print(a)#10
add(b=1,a=2) # 调用的时候,按照参数名去传递参数
add(b=1,2) #错误 SyntaxError: positional argument follows keyword argument
add(2,b=1) # 正确
add(2,a=1) # TypeError: add() got multiple values for argument 'a'
可以混用,但是关键字参数一定要放在后面,且位置还是不可以乱序
函数调用的时候不会去检查函数的类型
add(True,10) # 21
add('a',10) # 报错
#参数类型注解
sig = inspect.signature(add)
params = sig.parameters
print(params,type(params))
for v in params.values():
print(v)
和java相同,参数传递也是值copy(值传递)
def add(a,b):
total=0
for i in a:
total+=i #计算数值的和
for i in b:
total+=i
print(total)#输出total
a.append(4)#[1,2,3,4]
b.append(5)#[4,5,5]
a = [1,2,3]
b = [4,5]
add(a,b)
print(a,b)
#15
#[1,2,3,4][4,5,5]
不定长参数
在元组中的拆包中可以用*去代表若干剩下的参数
def add(*nums:int):
print(nums,type(nums))
add(1,2,3)
#输出(1, 2, 3)
# 推荐现成下面这样,标记好返回类型
def add(*nums:int)->int:
total = 0
for i in nums:
total+=i
return total
print(add(1,2,3,4))
带*号的不定长参数只能有一个
可以和其他的参数混用,Java不定长参数只能放在最后,python随便,但是有规则
形参(形式参数)
实参(实际参数)
函数调用的时候,实际参数的数量要和定义的形参数量一致
如果不强调,位置也一样。
位置可以通过名字来强调
add(b=1,a=2) # 调用的时候,按照参数名去传递参数
add(b=1,2) #错误 SyntaxError: positional argument follows keyword argument
add(2,b=1) # 正确
add(2,a=1) # TypeError: add() got multiple values for argument 'a'
可以混用,但是关键字参数一定要放在后面,且位置还是不可以乱序
函数调用的时候不会去检查函数的类型
add(True,10) # 21
add('a',10) # 报错
和java相同,参数传递也是值copy(值传递)
在元组中的拆包中可以用*去代表若干剩下的参数
def add(*nums:int): print(nums,type(nums)) add(1,2,3) #输出(1, 2, 3)# 推荐现成下面这样,标记好返回类型 def add(*nums:int)->int: total = 0 for i in nums: total+=i return total print(add(1,2,3,4))
带*号的不定长参数只能有一个
可以和其他的参数混用,Java不定长参数只能放在最后,python随便,但是有规则
1.不定项参数放在最后
def add(a,b,*c):#不定项参数放在最后
total=0
total+=a*100#a乘以100
total+=b*100#b乘以100
for i in c:#c中的所有值
total+=i
return total
print(add(1,2,3,4,5)
#132
2.不定项参数不放在最后
def fn(*a,b,c): print(a) print(b) print(c) #以关键字参数的形式传递 fn(1,2,3,b=4,c=5) def fn(a,*b,c): print(a) print(b) print(c) fn(1,2,3,4,c=5)
如果第一个参数位置直接使用一个*号,表示必须用关键字参数传递所有参数
def fn(*,a,b,c): print(a) print(b) print(c)
如果只有一个不定项参数,那不能使用关键字参数
def add(*nums): print(add(1,2,3,a=1))#不可以
作为形参可以接受其他的关键字参数,会将这些参数统一保存在一个字典里
不定项关键字形参只有一个,而且必须写在所有参数的最后
相当于若干个不定项的位置参数
相当于若干个不定项的关键字参数
def fn(**kwargs):
print(kwargs,type(kwargs))
for i in kwargs:
print(i)
#接收其他的关键字参数并统一保存在同一个字典中
fn(a=1,b=2,c=3,d=4)
# {'a': 1, 'b': 2, 'c': 3, 'd': 4}
参数的解包
def fn(a,b,c):
print(a)
print(b)
print(c)
t=1,2,3
fn(t)#产生报错
fn(*t) #输出abc
#1
#2
#3
传字典
def fn(a,b,c):
print(a)
print(b)
print(c)
# d = dict(a=1,b=2,c=3)
d = {'a':1,'b':2,'c':3}
fn(**d)
#输出123
#1
#2
#3
返回值
def add(*nums):
total=0
for i in nums:
total+=i
return total
#函数也可以返回函数
def fn()
def fn2():
print('hello')
return fn2
a=fn()
a()
print(fn,type(fn))
print(fn(),type(fn())
#hello
#
#.fn2 at 0x000001C21AFAB160>
函数的帮助文档
help()
dir()
```
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
作用域
作用域的分类:
全局作用域
程序开始的时候创建,程序结束的时候销毁
函数作用域
函数执行的时候穿件,调用结束销毁,每次调用都会参数一个新的函数作用域
def fn(a,b,c):
print(a)
print(b)
print(c)
# d = dict(a=1,b=2,c=3)
d = {'a':1,'b':2,'c':3}
fn(**d)
#输出123
#1
#2
#3
返回值
def add(*nums):
total=0
for i in nums:
total+=i
return total
#函数也可以返回函数
def fn()
def fn2():
print('hello')
return fn2
a=fn()
a()
print(fn,type(fn))
print(fn(),type(fn())
#hello
#
#.fn2 at 0x000001C21AFAB160>
函数的帮助文档
help()
dir()
```
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
作用域
作用域的分类:
全局作用域
程序开始的时候创建,程序结束的时候销毁
函数作用域
函数执行的时候穿件,调用结束销毁,每次调用都会参数一个新的函数作用域
help()
dir()
```
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
作用域
作用域的分类:
全局作用域
程序开始的时候创建,程序结束的时候销毁
函数作用域
函数执行的时候穿件,调用结束销毁,每次调用都会参数一个新的函数作用域
作用域的分类:
全局作用域
程序开始的时候创建,程序结束的时候销毁
函数作用域
函数执行的时候穿件,调用结束销毁,每次调用都会参数一个新的函数作用域
当我们使用变量的时候,会优先查找当前作用域,没有则到上一级查找
a = 10 # globe 全局变量, 不太建议去修改全局变量
def fn():
a = 20 # 函数内部变量
参数传递
java String类,本质char[]构成,java中数组是不可变长度
StringBuilder StringBuffer
append
** 值传递 ** 基本数据类型的值就是基本数据类型本身 对象类型就是对象的地址
命名空间
命名空间(namespace):是指变量存储的位置,每一个变量都是存储在指定的命名空间中的
每一个作用域都有一个对应的命名空间
全局命名空间,保存全局变量
函数命名空间,保存函数中的局部变量
java web中有一个范围概念,变量就是存储在这个范围里面的,这个范围实质就是一个字典
通过locals() 获取当前作用域的命名空间
scope = locals() #获取当前作用域的命名空间——即变量存储位置
print(scope,type(scope))
# 通过字典去拿取全局变量
print(scope['a1'])
# 创建一个全局变量 key-value c = 10000
# 一般不建议
scope['c'] = 10000
print(c)
def test():
a = 10
scope = locals()
print(scope['a'])
scope['b'] = 20
print(scope,type(scope))
# print(b) # 可以添加函数作用域内的变量b
global_scope = globals() # 在任意地方获取全局作用域
print(global_scope)
test()
#返回结果
{'a': 10, 'b': 20}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B3F3DA0880>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': 'f:/Python/Python代码/2022DWR/22_05_28/不定长参数练习.py', '__cached__': None,
'test': }
递归
函数自己调用自己一定要有边界
def fabo(num:int)->int:
if num == 1 or num == 2:
return 1
return fabo(num-1)+fabo(num-2)
print(fabo(10))
#f(1)=1 f(2)=1
#f(3)=f(2)+f(1)=2
#f(4)=f(3)+f(2)=3
#f(5)=......
#f(10)=f(9)+f(8)
#递归
#55
def factorial(n:int)->int:
if n == 1:
return 1
return n*factorial(n-1)
print(factorial(10))
#计算10!的阶乘
#3628800
高阶函数
高阶函数:接受函数作为参数,或者将函数作为返回的函数
fn = abs
print(fn(-10))
高阶函数:接受函数作为参数,或者将函数作为返回的函数
将函数赋值给一个变量,函数的参数是一个变量,所以我们是不是可以把函数作为另外一个函数的参数传递给他
fn = abs
print(fn(-10))
def add(a:int,b:int,func)->int:
return func(a) + func(b)
print(add(-10,10,fn))
##abs 返回数字的绝对值
#10
#20
内置高阶函数
map函数
map函数有两个参数,一个是函数,一个是(Iterable)可迭代对象,map函数就会将传入的函数一次在可迭代对象的每一个元素上用一次,并且把用完的结果作为新的可迭代对象返回
def fn(n:int)->int:
return n+1
arr = [1,2,3,4,5]
arr2 = map(fn, arr)#将arr中的字符串转化为列表
#例如arr=['1','2','3'] 返回arr2=[1,2,3]
# arr 不变 [1, 2, 3, 4, 5]
for i in arr2:
print(i)
s = {1,2,3,4}
print(set(map(fn,s)))
###返回值###
2
3
4
5
6
{2, 3, 4, 5}
reduce函数
在 Python2中是自带的,到Python3中在全局命名空间中删除了,需要 import
reduce 接受两个参数,一个是函数,一个是序列,reduce函数把每次计算的结果继续和下一个元素累计计算
from functools import reduce
def add(a:int,b:int)->int:
return a + b
#序列中reduce函数把每次计算的结果继续和下个元素累计计算
#print(reduce(add,arr))
# reduce(add,[1,2,3,4,5]) = add(add(add(add(1,2),3),4),5)
def trans(a:int,b:int)->int:
return a*10+b
print(trans(1,2))
#按照顺序排列成n位数
#12
# trans(trans(trans(1,2),3),4)
print(reduce(trans,[1,2,3,4,5]))
# 12345
def c2n(s):
d = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
return d[s]
# type(c2n('1'))
# m = list(map(c2n,'12345'))
# print(list(m))
print(reduce(trans,map(c2n,'12345')))
######返回值######
12
12345
12345
filter函数
map函数
map函数有两个参数,一个是函数,一个是(Iterable)可迭代对象,map函数就会将传入的函数一次在可迭代对象的每一个元素上用一次,并且把用完的结果作为新的可迭代对象返回
reduce函数
在 Python2中是自带的,到Python3中在全局命名空间中删除了,需要 import
reduce 接受两个参数,一个是函数,一个是序列,reduce函数把每次计算的结果继续和下一个元素累计计算
filter函数接受一个函数和一个序列,和map 不一样的地方,filter会把传入的函数依次用于每个元素,然后根据返回值是True还是False来决定是否保留这个元素
def is_odd(num:int)->bool:
return num%2==1
#返回奇数
print(list(filter(is_odd,[1,2,3,4,5,6])))
#[1, 3, 5]
def check_lens(s:str)->bool:
return len(s) > 5
print(check_lens('abcdefg'))
#判断字符串长度是否大于5
#True
for s in filter(check_lens,['abc','asdjsadsad','zhangsan','lisi','wangwu']):
print(s)
#返回长度大于5的字符串
#######返回值######
asdjsadsad
zhangsan
wangwu
sorted函数
sorted函数可以接受一个key函数,key函数用来实现自定义排序,还可以接受一个reverse的bool值决定正序还是倒序
sorted([10,5,8,-12,24,-9],key=abs,reverse=True)
def fn(func, items):
new_items = []
for i in items:
if func(i):
new_items.append(i)
return new_items
def f1(i):
return i%3 == 0
def f2(i):
return i>10
print(fn(f2,[1,20,5,6,12,24]))
#先进行f2的运算(即大于10的数)
#其次进行fn 输入大于10的数
#将f2换成f1则输出能被3整除的数
Lambda表达式
lambda表达式 匿名函数
可以用来创建一些简单的函数
语法:lambda 参数列表 : 返回值
def add(a,b):
return a+b
add(1,2)
#返回3
fn = lambda a,b: a+b
fn(3,5)
#返回8
(lambda a,b: a+b)(3,5)
#返回8
from functools import reduce
fn = lambda a,b: a+b
fn(3,5)
print(reduce(lambda a,b: a+b,[1,2,3,4,5]))
#15
fn(lambda i:i%3==0,[1,20,5,6,12,24])
fn(lambda i:i>10,[1,20,5,6,12,24])
闭包
闭包:将函数作为返回值返回
通过闭包可以创建一些只有当前函数能访问的变量,可以将一些私有的数据藏在闭包内
函数嵌套
将内部的函数作为返回值返回
内部函数可以使用外部函数的变量
在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。
上面这段话实际上解释了闭包的一个定义和两个作用:
- 定义:闭包就是能够读取外部函数内的变量的函数。(前面已经讲解过)
- 作用1:闭包是将外层函数内的局部变量和外层函数的外部连接起来的一座桥梁。(下一部分讲解)
- 作用2:将外层函数的变量持久地保存在内存中。(下一部分讲解)
局部变量无法共享和长久的保存,而全局变量可能造成变量污染,闭包既可以长久的保存变量又不会造成全局污染。
闭包使得函数内局部变量的值始终保持在内存中,不会在外层函数调用后被自动清除。
当外层函数返回了内层函数后,外层函数的局部变量还被内层函数引用
带参数的装饰器,那么一般都会生成闭包。
闭包在爬虫以及web应用中都有很广泛的应用。
def fn():
a = 10
def inner_fn():
print(a)
return inner_fn;
# r = fn()
# r()
fn()()
#10
#将内部的函数作为返回值返回
装饰器
log函数,称之为装饰器
装饰器的作用:可以在不修改原有代码的基础上,进行扩展
def log(func):
def print_log(*args,**kw):
print('begin')
r = func(*args,**kw)
print('end')
return r
return print_log
# add2 = log(add)
print(log(add)(1,5))
#虽然我也没有太看懂这段代码是要干嘛就是了
def sub(a,b):
return a - b
def fn(c='zhangsan'):
print(c)
log(fn)('lisi')
#在原有函数fn的基础上进行扩展
#使用@装饰器名 指定给某个方法加上指定的装饰器
@log
def fn(c='zhangsan'):
print(c)
fn()
装饰器可以有多个,按照由内向外的顺序依次装饰
@log2
@log
def fn(c='zhangsan'):
print(c)
fn()
''''''
begin2
begin
zhangsan
end
end2
带参数的装饰器:
def funA(fn):
# 定义一个嵌套函数
def say(arc):
print("Python教程:",arc)
return say
@funA
def funB(arc):
print("funB():", a)
funB("http://w")
#返回
#Python教程: http://w
sorted函数可以接受一个key函数,key函数用来实现自定义排序,还可以接受一个reverse的bool值决定正序还是倒序
lambda表达式 匿名函数
可以用来创建一些简单的函数
语法:lambda 参数列表 : 返回值
def add(a,b):
return a+b
add(1,2)
#返回3
fn = lambda a,b: a+b
fn(3,5)
#返回8
(lambda a,b: a+b)(3,5)
#返回8
from functools import reduce
fn = lambda a,b: a+b
fn(3,5)
print(reduce(lambda a,b: a+b,[1,2,3,4,5]))
#15
fn(lambda i:i%3==0,[1,20,5,6,12,24])
fn(lambda i:i>10,[1,20,5,6,12,24])
闭包
闭包:将函数作为返回值返回
通过闭包可以创建一些只有当前函数能访问的变量,可以将一些私有的数据藏在闭包内
函数嵌套
将内部的函数作为返回值返回
内部函数可以使用外部函数的变量
在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。
上面这段话实际上解释了闭包的一个定义和两个作用:
- 定义:闭包就是能够读取外部函数内的变量的函数。(前面已经讲解过)
- 作用1:闭包是将外层函数内的局部变量和外层函数的外部连接起来的一座桥梁。(下一部分讲解)
- 作用2:将外层函数的变量持久地保存在内存中。(下一部分讲解)
局部变量无法共享和长久的保存,而全局变量可能造成变量污染,闭包既可以长久的保存变量又不会造成全局污染。
闭包使得函数内局部变量的值始终保持在内存中,不会在外层函数调用后被自动清除。
当外层函数返回了内层函数后,外层函数的局部变量还被内层函数引用
带参数的装饰器,那么一般都会生成闭包。
闭包在爬虫以及web应用中都有很广泛的应用。
def fn():
a = 10
def inner_fn():
print(a)
return inner_fn;
# r = fn()
# r()
fn()()
#10
#将内部的函数作为返回值返回
装饰器
log函数,称之为装饰器
装饰器的作用:可以在不修改原有代码的基础上,进行扩展
def log(func):
def print_log(*args,**kw):
print('begin')
r = func(*args,**kw)
print('end')
return r
return print_log
# add2 = log(add)
print(log(add)(1,5))
#虽然我也没有太看懂这段代码是要干嘛就是了
def sub(a,b):
return a - b
def fn(c='zhangsan'):
print(c)
log(fn)('lisi')
#在原有函数fn的基础上进行扩展
#使用@装饰器名 指定给某个方法加上指定的装饰器
@log
def fn(c='zhangsan'):
print(c)
fn()
装饰器可以有多个,按照由内向外的顺序依次装饰
@log2
@log
def fn(c='zhangsan'):
print(c)
fn()
''''''
begin2
begin
zhangsan
end
end2
带参数的装饰器:
def funA(fn):
# 定义一个嵌套函数
def say(arc):
print("Python教程:",arc)
return say
@funA
def funB(arc):
print("funB():", a)
funB("http://w")
#返回
#Python教程: http://w
闭包:将函数作为返回值返回
通过闭包可以创建一些只有当前函数能访问的变量,可以将一些私有的数据藏在闭包内
函数嵌套
将内部的函数作为返回值返回
内部函数可以使用外部函数的变量
在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。
上面这段话实际上解释了闭包的一个定义和两个作用:
- 定义:闭包就是能够读取外部函数内的变量的函数。(前面已经讲解过)
- 作用1:闭包是将外层函数内的局部变量和外层函数的外部连接起来的一座桥梁。(下一部分讲解)
- 作用2:将外层函数的变量持久地保存在内存中。(下一部分讲解)
局部变量无法共享和长久的保存,而全局变量可能造成变量污染,闭包既可以长久的保存变量又不会造成全局污染。
闭包使得函数内局部变量的值始终保持在内存中,不会在外层函数调用后被自动清除。
当外层函数返回了内层函数后,外层函数的局部变量还被内层函数引用
带参数的装饰器,那么一般都会生成闭包。
闭包在爬虫以及web应用中都有很广泛的应用。
log函数,称之为装饰器
装饰器的作用:可以在不修改原有代码的基础上,进行扩展
def log(func):
def print_log(*args,**kw):
print('begin')
r = func(*args,**kw)
print('end')
return r
return print_log
# add2 = log(add)
print(log(add)(1,5))
#虽然我也没有太看懂这段代码是要干嘛就是了
def sub(a,b):
return a - b
def fn(c='zhangsan'):
print(c)
log(fn)('lisi')
#在原有函数fn的基础上进行扩展
#使用@装饰器名 指定给某个方法加上指定的装饰器
@log
def fn(c='zhangsan'):
print(c)
fn()
装饰器可以有多个,按照由内向外的顺序依次装饰
@log2
@log
def fn(c='zhangsan'):
print(c)
fn()
''''''
begin2
begin
zhangsan
end
end2
带参数的装饰器:
def funA(fn): # 定义一个嵌套函数 def say(arc): print("Python教程:",arc) return say @funA def funB(arc): print("funB():", a) funB("http://w") #返回 #Python教程: http://w



