Python学习--Day 15
- 视频来源:python视频 900集
113.带参数的装饰器-11
- 带参数的装饰器:要装三层,函数里面套函数里面套函数。在第1层返回第2层的函数名称,第2层返回第3层函数名称。如果想让函数带有参数,就要写三层函数,并依层数具体返回。
第一层函数outer()
负责接收参数、第二层decorate()
负责接收函数、第三层wrapper()
负责接收函数的参数。
def outer(a):
def decorate(func):
def wrapper(*args,**kwargs):
func(*args)
print('--地砖{}'.format(a))
return wrapper
return decorate
@outer(10)
def house(time):
print('我{}拿到毛坯房'.format(time))
house('2020年')
@outer(100)
def steert():
print('街道要地砖')
steert()
# 结果
# 我2020年拿到毛坯房
# --地砖10
# 新秀的街道要地砖
# --地砖100
- 总结:带参数的装饰器要写3层,最外层函数负责接收装饰器的参数,内层两个不变,记住第一层返回值是第二层的函数名称
114.装饰器应用之付款-12
- 习题课,登陆验证
跟着老师敲了一遍,失误比较大的地方就是global添加的位置写错了,必须要放到内层函数的里面。
import time
islogin = False
def login():
username = input('please input usernmae:')
password = input('please input password:')
if username == '12' and password == '1234':
return True
else:
return False
# 定义一个装饰器,进行付款验证
def login_required(fun):
def wrapper(*args, **kwargs):
global islogin # 注意添加位置
print('--付款--')
if islogin:
fun(*args, **kwargs)
else:
print('没登陆')
islogin = login()
print(islogin)
return wrapper
@login_required
def pay(money):
print('正在付款:{}元'.format(money))
print('付款中...')
time.sleep(2)
print('付款成功')
pay(1000) # 第一个付款的时候没有登录,付款失败
pay(800) # 第二个付款的时候登录了,付款成功
115.回顾+作用域
- 内容回顾:闭包(内层函数,引用变量,返回内层函数名称),装饰器(万能装饰器、带参数的装饰器、多层装饰器)
- 作用域:LEGB,L:local,本地,局部作用域;E:enclosing,嵌套,当前的上层,可以理解为‘半局部作用域’,G:global,全局变量,全局作用域;B:built-in,内置的,系统自带。如果解释器沿着上述的过程搜索后没有,则报错。
116.匿名函数
- 匿名函数定义:
lambda 参数1, 参数2...: 运算
,用于创建匿名函数。
举个例子:
s = lambda a, b: a + b
print(s)
# 输出结果:
# <function <lambda> at 0x00000229E4B72EA0>
s(2,3)
print(s(2,3))
# 输出结果:
# 5
- 匿名函数作为参数出现:
func(1,2,lambda x,y:x + y)
def func(x,y,func):
print(x,y)
print(func)
print(func(x,y))
func(1,2,lambda x,y:x + y)
# 输出结果:
# <function <lambda> at 0x000001F0D48AF158>
# 3
117.内置函数+匿名函数
- 内置函数与匿名函数的结合(有点难以记忆,自己做的时候可能不会这样简介,值得背一下)
max(*args, key = None)
,key的本质是函数,按照什么进行比较。
举例:求列表中的‘a’对应的关键字的最大值
list2 = [{'a':10,'b':20},{'a':13,'b':20},{'a':9,'b':20},{'a':29,'b':20}]
m = max(list2, key = lambda x:x['a'])
print(m)
- map函数结合匿名函数
map(func,*iterables)
返回map object
list1 = [12,3,5,6,3,5,67]
result = map(lambda x: x+2,list)
print(map)
print(list(map))
# 输出结果:
# <class 'map'>
# [14, 5, 7, 8, 5, 7, 69]
- 匿名函数的扩展:
匿名函数lambda可以有更复杂的小功能:
func1 = lambda x : x if x%2==0 else x + 1
func1 = lambda x : x if x%2==0 else x + 1
result = func1(5)
- 匿名函数扩展与内置函数的结合:
list1 = [12,3,5,6,3,5,67]
result = map(lambda x : x if x%2==0 else x + 1,list1)
print(list(result))
# 返回结果:
# [12, 4, 6, 6, 4, 6, 68]
- reduce()函数:对列表中的元素进行加减乘除运算的函数,不是系统内置函数,需要
from functool import reduce
reduce(function, sequence, initial = None)
:在序列seq的每一个元素上都会使用一次function
运算流程:对3,5进行lambda,得到8;继续对8,7进行lambda,得到15,依次类推;注意当元组仅仅有一个元素的时候,会使用默认值initial = None,在这里就是默认为0;如果刻意的改变initial,则会改变。
from functools import reduce
tuple1 = (3,5,7,8,9,1)
result = reduce(lambda x, y: x + y,tuple1)
print(result)
# 结果打印:33
tuple2 = (1,)
result2 = reduce(lambda x, y: x + y,tuple2)
print(result2)
# 结果打印:1
result3 = reduce(lambda x, y: x + y,tuple2,10) # 使用initial = 10
print(result3)
# 结果打印:11
- 老师希望大家自行进行减法和乘法、除法的问题:
没什么特别的,就是延续上面的计算过程。
from functools import reduce
tuple1 = (3,5,7,8,9,1)
result = reduce(lambda x, y: x - y,tuple1)
print(result)
result1 = reduce(lambda x, y: x / y,tuple1)
print(result1)
result2 = reduce(lambda x, y: x * y,tuple1)
print(result2)
118.内置函数(filter,sorted,reduce)+匿名函数
- filter()——过滤功能
filter(function or None, iterable)
过滤一个可遍历的对象中满足func条件的元素。注意filter的func的返回值必须是布尔类型的。
list1 = [1,2,34,6,7,89]
result = filter(lambda x:x>10,list1) # 筛选列表中大于10的元素
print(list(result))
# 打印结果:
# [34, 89]
- 排序sorted()
sorted(iterable,key,reverse)
key=func指定排序的对象
students = [{'name':'tom','age':20},{'name':'Lucy','age':19},{'name':'lily','age':13},{'name':'mark','age':13},{'name':'jack','age':23},{'name':'steven','age':18}]
io = sorted(stuedents,key = lambda x:x['age'])
print(io)
# 返回结果:
# [{'name': 'lily', 'age': 13}, {'name': 'mark', 'age': 13}, {'name': 'steven', 'age': 18}, {'name': 'Lucy', 'age': 19}, {'name': 'tom', 'age': 20}, {'name': 'jack', 'age': 23}]
- 总结:以下都可以使用到lambda进行结合
max()、min()、sorted()与key结合
map()、reduce()、filter()与func类似,直接指明func就可以
119.递归函数
-
递归函数:函数自己调用自己
-
递归函数的特点:①一定要设定终点,否则会报错;②通常有一个入口;③自身调用自身
-
普遍的格式如下
def func(?)
if 退出条件:
return 退出返回值
return func(??)
- 举例子:
求列表的累加和
def sum(n):
if n==0:
return 0
else:
return n + sum(n-1)
print(sum(10))
-
如果递归没有合适的退出条件,python解释器会报错:
RecursionError: maxinum recursion depth exceeded while calling a Python object
,就是递归在无限进行,没有退出条件导致python解释器报错。 -
感觉老师只是讲了一个皮毛,记得以前学数据结构的时候使用递归我是真的不会写。。。
120.总结函数
- 函数总结
对前面内容的快速总结,总结了15分钟,没有新东西。
121.文件操作open简介
- 文件open()函数,打开文件的操作,open的参数如下:
open(file,mode=‘r’, buffering = None, encoding = None, errors = None, newline = None, closefd = None, opener = None) - 文件说明:在函数def中敲击三次引号,自动提供文档说明的注释提示项,开发中要经常使用。
- mode的说明:
r:read,读;w:write,写;rb:b代表二进制,read binary,通常用于纯文本、图片、音乐、电影等;同理wb。读、写是从pycharm的角度去看的,如果说读文件,就是说从其他地方将文件导入pycharm;如果说写文件,就是说pycharm将本身的内容写给其他人。 - buffering的说明:(缓存)
缓存是为了缓冲传输压力,但是python解释器的缓存如果很大,会影响运行速度 - encoding的说明:(编码方式)
可以指明也可以不指明。
122.文件操作之读取文件
- 基础的open()函数参数:
open(file,mode=‘r’, buffering = None, encoding = None) - mode的各种类型
rt是默认类型,就是reading并作为txt文件。
字符 | 含义 |
---|---|
‘r’ | open for reading(default) |
‘w’ | open for writing, truncating the file first |
‘x’ | create a new file and open it for writing |
‘a’ | open for writing, appending to the end of the file if it exists |
‘b’ | binary mode |
‘r’ | text mode(default) |
‘+’ | open a disk file for updating (reading and writing) |
‘U’ | universal newline mode(deprecated) |
- 书写代码示例
如下,是在本机的pycharm进行文件阅读的代码。
str = open(r'C:\Users\10727\Desktop\q.txt')
这句话是说,open某路径中的一个文件,并将这个文件赋值给str,其中open(r'---')
中的r代表的是原样阅读,避免内部出现转义字符,下次乃至以后使用的时候就当作必要参数进行调用就可以了;其次,括号内的路径要使用绝对路径。如果没有找到文件(即路径或文件名有问题),就会报错:FileNotFoundError: No such file or directory: '...'
str = open(r'C:\Users\10727\Desktop\q.txt')
cu = str.read()
print(cu)
- Open的进一步说明
如果你要打开的文件与当前文件在同一个文件夹中,直接使用文件名filename就可以,不用再写路径path。
open(r'path/filename','rt')
返回值是一个流文件,对这个流文件可以使用read()方法将内容传输给其他变量。将其他文件的内容传到当前python文件的基本流程如下:
stream = open(path)-----content = stream.read()
- read()家族
read()——正常读取文件
readable()——判断这个文件是不是可以读取,返回值是True或False
readline()——仅仅读文件的一行(见下面的具体说明)
readlines()——将所有行读出并将内容保存到列表中,list1 = stream.readlines()
- readline()
如果前面已经使用了read()进行了阅读操作,那么流文件全部消失了,在管道中没有文件流,就不会有结果。因此想使用readline()的时候,就要单独调用;readline()在读文件的时候,默认将读一行就加一个换行符\n
。
用readline()写出read()的效果:
while True:
line = stream.readline()
print(line)
if not line:
break
- 使用read读图片文件,要指定mode为b,即二进制格式类型。如果没有指明mode会使用默认的rt进行阅读,会报错。
stream = open(r'C:\Users\10727\Desktop\q.jpg','rb')
con = stream.read()
print(con)
发现好多之前讲解过的内容都有点忘记了。。比如字典集合的一些函数,看来要找时间准备复习一下了;最近还要看花书,还有点想学学爬虫技术,日常不务专业。。。