Python学习--Day 15

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)

发现好多之前讲解过的内容都有点忘记了。。比如字典集合的一些函数,看来要找时间准备复习一下了;最近还要看花书,还有点想学学爬虫技术,日常不务专业。。。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页