装饰器
概念:是一个闭包,把函数当作参数返回一个替代版的函数,本质上就是一个返回函数的函数。
#简单的装饰器
def func1():
print("I love you")
def outer(func):
def inner():
print("***********")
func()
return inner
f = outer(func1)
f()
输出:
********
I love you
复杂一点的装饰器
def outer(func):
def inner(age):
if age < 0:
age = 0
func(age)
return inner
say = outer(say)
通用装饰器
def outer(func):
def inner(*args,**kwargs):
#添加修改的功能
func(*args,**kwargs)
return inner
@outer # say = outer(say)
def say(name,age): #函数的参数理论上不限制个数,但实际上最好不要超过6,7个
print("my name is %s,i am %d years old"%())
偏函数
把一个参数固定,形成一个新的函数
int3 = functools.partial(int, base = 2) #把输入的数当作2进制转为10进制输出
print(int3("111"))
输出:
7
变量的作用域
作用域:变量可以使用的范围
程序的变量并不是在所有位置都能使用,访问的权限决定于变量在哪里赋值的。
作用域:
- 局部作用域
- 全局作用域
- 内建作用域*(不常用)
异常处理
格式:
try:
语句t
except 错误码 as e:
语句1
except 错误码 as e:
语句2
……
except 错误码 as e:
语句n
else:
语句e
注意:else语句可有可无
作用:用来检测try语句块中的错误,从而让except语句捕获错误信息并处理
- 逻辑:
当程序执行到try-except-else语句时
- 如果try“语句t”执行出现错误,会匹配第一个错误码,如果匹配上就执行对应的“语句”
- 如果当try“语句t”执行出现错误,没有匹配的异常,错误将会被提交到上一层的try语句。或者到程序的最上层。
- 如果当try“语句t”执行没有出现错误,执行else下的“语句e”(你得有)
eg:
try:
print(3 / 0)
except ZeroDivisionError as e:
print("除数为0")
输出:
除数为0 #程序没有因为遇到错误而截至。
使用except而不使用任何错误类型(一般情况下的解决办法)
try:0
print(4 / 0)
except:
print("程序出现了异常")
使用ecxept带着多种异常
try:
print(5 / 0)
except (NameError, ZeroDivisionError):
print("出现了NameError或ZeroDivisionError")
特殊:
- 错误其实是类class,所有的错误都继承自BaseException,所以在捕获的时候,它捕获了该类型的错误,还把子类一网打尽。
(尽量把儿子放前面,爸爸放后边) - 跨越多层调
try-except-finally
格式:
try:
语句t
except 错误码 as e:
语句1
except 错误码 as e:
语句2
……
except 错误码 as e:
语句n
finally:
语句f
作用:语句t无论是否有错误,都将执行最后的语句f
(用于文件处理)
断言
def funv(num, div)
assert (div != 0),"div不能为0" #断言
return num / div
print(func(10,0))
输出:
assert (div != 0),"div不能为0"
AssertionError:div不能为0
文件读写
过程:
1. 打开文件
open( path,flag[, encoding][,error])
path:要打开文件的路径
flag:打开方式
(前6个常用)
- r:以只读的方式打开文件,文件的描述符放在文件的开头。
- rb:以二进制格式打开一个文件用于只读,文件的描述符放在文件的开头。
- r+:打开一个文件用于读写,文件的描述符放在文件的开头。
- w:打开一个文件用于写入,如果该文件已经存在,会覆盖;如果不存在,会创建新文件。
- wb:打开一个文件,只用于写入二进制,如果该文件已经存在,会覆盖;如果不存在,会创建新文件。
- w+:打开一个文件用于读写,如果该文件已经存在,会覆盖;如果不存在,会创建新文件。
- a:打开一个文件用于追加,如果该文件已经存在,文件描述符会放到末尾
- a+:
encoding:编码方式
error:错误处理
打开文件代码
path = r"文件路径"
#ignore 忽略错误
#f = open(path, "r", encoding = "utf-8", errors = "ignore")
f = open(path, "r")
2. 读文件内容
- 1.读取文件全部内容
#适用于读小文件
f = open(r"路径(由盘具体到格式)")
str1 = f.read()
print(str1)
- 2.读取指定字符数
str2 = f.read(10)
print("*" + str2 + "*“)
str3 = f.read(10)
print("*" + str3 +"*")
输出:
*This is a *
*day and i *
- 3.读取整行,包括"\n"字符
str4 = f.readline()
print(str4)
str5 = f.readline()
print(str5)
- 4.读取所有行并返回列表
list7 = f.readlines()
print(list7)
- 5.若给定的数字大于0,返回实际size字节的行数
list8 = f.readlines(25)
print(list8)
- 6.修改描述符的位置
f.seek(0)
str9 = f.read()
3. 关闭文件
f.close()
一个完整的过程:
try:
f1 = open('path(文件名.格式)',"r",encoding = "utf-8")
print(f1.read())
finally:
if f1:
f1.close()
简化版代码
with open(‘path(文件名.格式)’, "r", encoding = "utf-8") as f2:
print(f2.read())
4.写文件
- 1.将信息写进缓冲区
f = open(path, "w")
f.write("hello world")
- 2.刷新缓冲区
直接把内部缓冲区的数据立刻写入文件,而不是被动的等待,自动刷新缓冲区。
f.flush()
编码与解码
编码解码格式要一致
path = r"路径"
with open(path, "wb") as f1:
str = "hello world"
f1.write(strr.encode("utf-8")) #编码
with open(path, "rb") as f2:
data = f2.read()
print(data)
print(type(data))
newData = data.decode("utf-8") #解码
print(newData)
print(type(newData))
输出:
b'hello world'
<class 'bytes'>
hello world
<class 'str'>