文章目录
正则相关函数
import re
search 和 match
通过正则匹配出第一个对象返回,通过group取出对象中的值
strvar = "1d2 3&5"
obj = re.search("(\d).*?(\d)",strvar)
print(obj)
res = obj.group()
print(res)
# 拿到分组当中的值用groups
res = obj.groups()
print(res)
# 拿到分组里的元素个数 lastindex
res = obj.lastindex
print(res)
# search 和 match 用法一样,区别在与match在正则的前面加了一个^ [必须以..开头]
# search 只需要在正则的前面加上^ 就可以取代match
strvar = "uuyydfopopopop3434sdf234"
# obj = re.search("^d.*?\d",strvar) #c 等价于match
obj = re.search("d.*?\d",strvar)
res = obj.group()
print(res,"<search>")
# match
obj = re.match("d.*?\d",strvar)
print(obj) # None 必须以d作为字符串的开头
# res = obj.group()
# print(res)
split 切割
strvar = "alex|wusir|secret,boy"
lst = strvar.replace(",","|").split("|")
print(lst)
strvar = "alex,wusir|secret%boy"
res = re.split(r"[,|%]",strvar)
print(res)
# 可以选择分割的次数
res = re.split(r"[,|%]",strvar,1)
print(res)
strvar = "alex234234wusir2secret909090boy"
res = re.split(r"\d+",strvar)
print(res)
sub 替换
strvar = "alex,wusir|secret%boy"
res = re.sub("[,|%]","-",strvar)
print(res)
# 后面可以选择替换的次数
res = re.sub("[,|%]","-",strvar,1)
print(res)
# subn 与 sub 用法一样,最大的区别在于返回值 ,返回一个元组,包含替换的次数
res = re.subn("[,|%]","-",strvar)
print(res)
finditer 匹配字符串中相应内容,返回迭代器
finditer
和findall
用法一样,区别在于返回的是迭代器- 迭代器里面是一个一个的对象,想获取对象的值用
group()
strvar = "sdfsdff&*&*%^%234sdfsdfskdjfk3sdf23"
lst = re.findall("\d",strvar)
print(lst)
res = re.finditer("\d",strvar)
print(res)
from collections import Iterator
print(isinstance(res,Iterator))
it = re.finditer("\d",strvar)
# lst = list(it)
# print(lst)
obj = next(it)
res = obj.group()
print(res)
for i in it:
res = i.group()
print(res)
compile 指定一个统一的匹配规则
写一套正则,程序就需要重新编译一次,
同一个正则多处使用,反复编译会浪费时间
这样的话,就可以使用compile
来定义一次,终身受益
rule = re.compile("\d+")
print(rule)
strvar = "sdfsdfs234kjkjk*(*9343dsf3"
obj = rule.search(strvar)
print(obj)
print(obj.group())
lst = rule.findall(strvar)
print(lst)
正则表达式的修饰符
re.I
使匹配对大小写不敏感
re.M
多行匹配,影响^
和 $
re.S
使 .
匹配包括换行在内的所有字符
- re.I 使匹配对大小写不敏感
strvar = "<h1>sdfsfsdfsd</H1>"
# rule = re.compile("<h1>.*?</h1>")
# 推荐使用flags来指定修饰符,预防未知错误
rule = re.compile("<h1>.*?</h1>",flags = re.I)
obj = rule.search(strvar)
print(obj)
print(obj.group())
- re.M 多行匹配,影响 ^ 和 $
"""
# 每一行都单独的去匹配,卡主开头和结尾,忽略换行. 每一行都拿出来单独匹配
"<h1>sdfsf</h1>"
"<h1>dd22</h1>"
"<h1>aabb</h1>"
"""
strvar = """<h1>sdfsf</h1>
<h1>dd22</h1>
<h1>aabb</h1>"""
rule = re.compile("^<h1>(.*?)</h1>$",flags= re.M)
lst = rule.findall(strvar)
print(lst)
- re.S 使 . 匹配包括换行在内的所有字符
strvar = '''give
123mefive
'''
rule = re.compile("(.*?)mefive",flags = re.S)
obj = rule.search(strvar)
print(obj.group())
类中的方法
- 普通方法: 没有参数,只能类调用
- 绑定方法:
- (1)绑定到对象(自动传递对象参数)
- (2)绑定到类(自动传递类参数)
- 静态方法: 无论是类还是对象,都能调用的方法
class Dog():
def __init__(self,name):
self.name = name
# 普通方法
def jiao():
print("小狗看见人就旺旺")
# 绑定到对象方法
def tian(self):
print("小狗喜欢舔")
# 绑定到类方法
@classmethod
def la(cls):
print(cls)
print("小狗会吃屎")
# 静态方法
@staticmethod
def jump():
print("小狗喜欢跳起来接飞盘")
obj = Dog("迈克尔·蛋")
# (1) 普通方法
Dog.jiao()
# 对象无法调用
# (2) 绑定到对象方法
obj.tian()
# Dog.tian(134) # 如果硬要使用类来调用,满足实参形参一一对应.
# (3) 绑定到类方法
Dog.la()
# 用对象调用绑定到类的方法是可以的,先找出该对象所归属的类是谁,然后在传递这个类
obj.la()
# (4) 静态方法
obj.jump()
Dog.jump()
装饰器 @property
可以把方法变成属性使用
作用 : 控制类内成员的获取 设置 删除
- 获取
@property
- 设置
@自定义名.setter
- 删除
@自定义名.deleter
方法一
class MyClass():
def __init__(self,name):
self.name = name
#获取
@property
def username(self):
return self.name
# pass
#设置
@username.setter
def username(self,val):
self.name = val
# pass
#删除
@username.deleter
def username(self):
del self.name
# pass
obj = MyClass("马巨强")
# 获取
print(obj.username)
# 设置
obj.username = "张国成"
print(obj.username)
# 删除 del 调用删除相关的方法
del obj.username
# print(obj.username)
方法二
class MyClass2():
def __init__(self,name):
self.name = name
# 获取值的方法
def get_username(self):
return self.name
# 设置值得方法
def set_username(self,val):
self.name = val
# 删除值得方法
def del_username(self):
del self.name
# 在类加载的时候,自动把这些方法当成参数进行传递,不是在调用时传递的.
# property 接受三个参数,必须按照顺序传递:(1)获取值的方法(2)设置值得方法(3)删除值得方法
username = property(get_username,set_username,del_username)
address = property(get_username,set_username,del_username)
obj = MyClass2("姚乘政")
# 获取当前username
print(obj.username)
# 设置值
obj.username = "ccc"
# 获取值
print(obj.username)
# 删除值
del obj.username
# print(obj.username)
obj.address = "深圳市区"
print(obj.address)
del obj.address
# print(obj.address)
异常
程序错误分为两种 : 语法错误 和 异常错误
- 语法错误:代码没有按照python规定语法去写,发明创造产生的错误
- 异常错误:在代码语法正确的前提下,程序报错就是异常
try...except...
基础语法 用于解决程序异常问题
aise
可以主动抛异常,异常类可以自定义
异常分类
异常类 | 说明 |
---|---|
IndexError | 索引超出序列的范围 |
KeyError | 字典中查找一个不存在的关键字 |
NameError | 尝试访问一个不存在的变量 |
IndentationError | 缩进错误 |
AttributeError | 尝试访问未知的对象属性 |
StopIteration | 迭代器没有更多的值 |
AssertionError | 断言语句(assert)失败 |
EOFError | 用户输入文件末尾标志EOF(Ctrl+d) |
FloatingPointError | 浮点计算错误 |
GeneratorExit | generator.close()方法被调用的时候 |
ImportError | 导入模块失败的时候 |
KeyboardInterrupt | 用户输入中断键(Ctrl+c) |
MemoryError | 内存溢出(可通过删除对象释放内存) |
NotImplementedError | 尚未实现的方法 |
OSError | 操作系统产生的异常(例如打开一个不存在的文件) |
OverflowError | 数值运算超出最大限制 |
ReferenceError | 弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象 |
RuntimeError | 一般的运行时错误 |
SyntaxError | Python的语法错误 |
TabError | Tab和空格混合使用 |
SystemError | Python编译器系统错误 |
SystemExit | Python编译器进程被关闭 |
TypeError | 不同类型间的无效操作 |
UnboundLocalError | 访问一个未初始化的本地变量(NameError的子类) |
UnicodeError | Unicode相关的错误(ValueError的子类) |
UnicodeEncodeError | Unicode编码时的错误(UnicodeError的子类) |
UnicodeDecodeError | Unicode解码时的错误(UnicodeError的子类) |
UnicodeTranslateError | Unicode转换时的错误(UnicodeError的子类) |
ValueError | 传入无效的参数 |
ZeroDivisionError | 除数为零 |
#IndexError 索引超出序列的范围
listvar = [1,2,3,4,5]
res = listvar[999]
# KeyError 字典中查找一个不存在的关键字
dic = {"a":1,"b":2,"鼓上骚":"石阡","花和尚":"鲁智深","智多星":"吴用"}
print(dic["母夜叉"])
# NameError 尝试访问一个不存在的变量
print(wangwen)
# IndentationError 缩进错误
if 5==5:
print(111)
print(22)
# AttributeError 尝试访问未知的对象属性
class MyClass():
a = 5
b = 6
obj = MyClass()
obj.c
# StopIteration 迭代器没有更多的值
it = iter(range(3))
for i in it:
print(i)
res = next(it)
# AssertionError 断言语句(assert)失败
'''
# 猜一猜 3大于1么? 如果3大于1 成立 没有任何反应
# 如果猜错了,直接抛异常
# 一般用在程序测试中
'''
assert 3<1
"""
if 3<1:
print("成立")
"""
异常处理
try: code1 code2 ... except: code1 code2
把有可能出现异常的代码放到try
这个代码块当中,
如果出现了异常错误,直接走except
这个代码块
- 异常处理基本语法
try:
lst = [1,2,3,4]
print(lst[999])
except:
# print("这个程序有错误~")
pass
- 多分支条件的异常处理
except + 异常错误类
特指这种异常错误发生时,走该分支
try:
# lst = [4,5,6,67]
# print(lst[999])
# dic = {"a":1}
# print(dic['b'])
print(wangwen)
# 特指IndexError , 索引越界错误
except IndexError:
print("走到这里,说明报的是索引下标越界错误.")
except KeyError:
print("走到这里,说明报的是字典的键出现错误")
except:
# 条件都不满足 , 就走except分支
print("有程序错误")
- 处理迭代器越界错误
借助异常处理类,接受生成器函数中的 return
返回值
def mygen():
yield 1
yield 2
return "done"
# 实例化生成器函数 产生生成器对象 简称 生成器
gen1 = mygen()
try:
res = next(gen1)
res = next(gen1)
res = next(gen1)
print(res)
# as 就是用来起名字的. 给StopIteration的类[对象]起名字
except StopIteration as e:
'''
当我们打印对象的时候,触发__str__魔术方法
在StopIteration这个类当中,自动接受异常return 的返回值
通过打印对象触发__str__方法,进而把返回值打印出来.
'''
print(e)
主动抛出异常 raise
BaseException
是所有异常处理类的父类(超类 基类) (子类的别名:衍生类,派生类)
Exception
是所有普通错误处理类的父类
raise + (异常处理类 或 异常处理的对象)
try:
raise
except:
pass
res = issubclass(Exception,BaseException)
print(res) # True
- 完整写法
try:
# 必须嵌入在try这个代码块里面使用;
raise BaseException
except BaseException:
print("这个程序抛出了异常")
# 简写写法
try:
raise
except:
print("程序异常")
- 自定义异常类
# return_errorinfo 必须要依靠抛异常的形式才能触发获取当前的行号或者文件名
def return_errorinfo(n):
import sys
f = sys.exc_info()[2].tb_frame.f_back
if n==1:
return str(f.f_lineno) #返回当前行数
elif n == 2:
return f.f_code.co_filename #返回文件名
def get_info(n):
try:
raise
except:
return return_errorinfo(n)
# 如果想要自定义异常类,必须继承所有异常类的父类BaseException
class MyException(BaseException):
def __init__(self,err_num,err_msg,err_line,err_filename):
# 打印错误号
self.err_num = err_num
# 打印错误信息
self.err_msg = err_msg
# 打印错误的行号
self.err_line = err_line
# 打印错误文件
self.err_filename = err_filename
human_sex = "中性"
try:
if human_sex == "中性":
raise MyException(1001,"人类没有中性",get_info(1),get_info(2))
except MyException as e:
# 打印错误号
print(e.err_num)
# 打印错误信息
print(e.err_msg)
# 打印错误的行号
print(e.err_line)
# 打印错误文件
print(e.err_filename)