Python学习笔记--面向对象、类、属性、继承、正则表达式、错误和异常
Python学习笔记--
Python面向对象
面向对象与面向过程的区别
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了:面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
其实就是两句话,面向对象就是高度实物抽象化、面向过程就是自顶向下的编程!
对象:现实中任何事物都可以称之为对象,有自己的独特的特点。属性是用来描述具体某个对象的特征。例如小明身高180,体重70千克,身高和体重就是属性。 面向对象的思想就是把一切事物都看成对象,而对象一般都是由属性和方法组成。 属性属于对象静态的一面,用来形容对象的一些特性。方法属于对象动态的一面,例如,小明会跑,会说话。跑,说话这些行为就是对象的方法! 类:具有同种属性的对象称为类,。比如,“人"就是一类,其中的人名比如小明,小红等都是对象。类相当于一个模板,他定义了它所包含的全体对象的公共特征和功能,对象是类的实例化。所以我们一般在做程序的时候一般都不用类名的,比如我们在叫小明的时候,不会喊”人,你干嘛呢!“而是说的是“小明,你在干嘛呢!"面向对象有三大特性:封装性,继承性和多态性
面向过程:
优点是性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源。而unyx\Unix等一般采用面向过程开发,性能是最重要的因素。缺点是没有面向对象易维护,易复用,易扩展。可维护性差,不易修改。
面向对象:
优点是易维护,易复用,易扩展。由于面向对象由封装,继承,多态性的特性,可以设计出耦合度低的系统,使系统更加灵活,更加易于维护。 缺点是性能比面向过程低
85-面向对象基础语法
# python中的面向对象主要学习类和对象
'''
类是:多个具有特殊功能的个体的集合.比如:人类、猫类
对象:在一个类中,一个其有特殊功能的个体,能够帮忙解决某件特定的事情,也被称为实例
两者之间的关系:类是用于描述某一类对象的共同特征,前对象是类的具体的存在
在程序中,一般要先定义类,然后通过定义的类创建对象,完成各种操作。
'''
'''
类的定义:
class 类名:
属性
方法
说明:
1.python屮使用class关键字来定义类。
2.类名只要是合法的标识符即可,但是要遵守大驼峰命名法则.
3.通过缩进来区分类体,
4.类体一般包含两个部分:属性和方法.(属性就是一些描述静态信息的,比如人的姓名\年龄\性别等等。方法一般使用函数表示,用来实现具体的功能。
'''
class Dog:
# 属性
name = '旺财'
age = 3
color = '白色'
sex = '雄'
# 方法
def bark(self):
print('汪汪汪')
def eat(self):
print('吃狗粮')
def sleep(self):
print('睡觉')
# 通过Dog类名创建对象
dog_1 = Dog() # dog_1是dog类的实例
print(dog_1) # <__main__.Dog object at 0x0000020EA0EA6D30>
# 通过对象访问属性
print(dog_1.name) # 旺财
print(dog_1.age) # 3
print(dog_1.color) # 白色
# 通过对象访问方法
dog_1.bark() # 汪汪汪
dog_1.eat() # 吃狗粮
86-面向对象构造函数
# 定义类
class Student():
# 构造函数,在此处设置对象属性
def __init__(self, name, age):
self.name = name
self.age = age
print(self.name,self.age,'构造函数的触发时机:创建对象完毕后,给对象属性赋值时,自动触发。。。。')
def run(self):
print(self.name, '跑步的方法')
def eat(self):
print(self.name, '吃东西的方法')
# 通过类创建对象
stu_1 = Student('小明', 18)
print(stu_1) # <__main__.Student object at 0x0000020A6A0A0E50>
stu_1.run() # 小明 跑步的方法
# 通过类创建对象
stu_2 = Student('小红', 19)
print(stu_2) # <__main__.Student object at 0x0000020A6A0A0E50>
stu_2.run() # 小红 跑步的方法
'''
1.构造函数:不用手动调用,当创建完对象,给对象赋值时,会自动触发,
2.构造函数主要用于项目的初始化操作,比如连接数据库等
3.self 代表当前对象
'''
87-面向对象析构函数
# 定义类
class Fish():
# 构造函数
def __init__(self, color, name):
self.color = color
self.name = name
# 游泳方法
def swim(self):
print("在大海游来游去.....")
# 析构函数
def __del__(self):
print("析构函数的触发时机:对象被销毁时,自动触发.....")
# 创建对象
fish_1 = Fish("blue", "小丑鱼")
fish_1.swim() # 调用方法
print(fish_1.color) # 访问属性
print(fish_1.name) # 访问属性
# fish_2 = Fish("yellow", "大丑鱼")
'''
总结:析构函数主要用于关闭数据库或者关闭文件等操作
'''
88-类属性和对象属性
# 定义类
class Dog():
# 类属性
name = '八个'
# 构造函数:定义在构造函数中的属性(对象属性)
def __init__(self, age, color):
self.age = age
self.color = color
# 创建对象
dog_1 = Dog(3, 'white')
# 通过类访问类属性(推荐)
print(Dog.name) # 八个
# 通过对象访问类属性(不推荐)
print(dog_1.name) # 八个
# 通过对象修改对象属性
print(dog_1.age) # 3
dog_1.age = 4
print(dog_1.age)
# 通过类修改类属性
print(Dog.name) # 八个
Dog.name = '小黑'
print(Dog.name) # 小黑
'''
总结:
1.一般情况下使用类名完成对类属性的访问和修改
2.一般情况下使用对象名完成对对象属性的访问和修改
'''
89-类方法和静态方法
# 定义类
class Animal():
# 类属性
name = '动物'
# 构造函数:设置对象的属性
def __init__(self, name, sex):
self.name = name
self.sex = sex
# 对象的方法
def eat(self):
print('吃吃吃')
'''
类方法:
1.通过@classmethod 装饰器修饰的方法就是类方法
2.类方法可以通过类名或对象名调用,但是一般情况下使用类名调用(节省内存)
3.类方法中没有self.在类方法中不可以使用其他对象的属性和方法
4.类方法中一般会有一个参数cls,cls仅仅是一个变量名称,可以用其他的变量名来代替,一般情况下会直接使用cls,因为cls是class的简写
5.cls 代表的是当前类
'''
# 类方法
@classmethod
def get_name(cls):
print('我是类方法')
'''
静态方法:
1.通过@staticmethod装饰器修饰的方法就是静态方法
2.通过类名或者对象名调用静态方法,一般使用类名调用(节省内存)
3.在静态方法中没有cls这个形式参数,在静态方法中一般不推荐调用其他的方法(对象的方法)类方法\静态方法)
4.静态方法一般是一个单独的方法,只是写在类中
'''
@staticmethod
def get_age():
print('我是静态方法')
# 创建对象
a = Animal('小花', '女')
# 通过对象名调用对象方法
a.eat() # 吃吃吃
# 通过类名调用类方法(推荐)
Animal.get_name() # 我是类方法
# 通过对象名调用类方法(不推荐)
a.get_name() # 我是类方法
# 通过类名调用静态方法(推荐)
Animal.get_age() # 我是静态方法
# 通过对象名调用静态方法(不推荐)
a.get_age() # 我是静态方法
90-私有属性和私有方法
# 定义类
class Girl():
# 构造函数
def __init__(self, name, age, height):
self.name = name
self.age = age
self.height = height
# 私有属性:在属性名前面加两个下划线
self.__weight = 50
# 定义一个方法,提供给类的外部访问私有属性,但是一般会设置限定条件,当条件满足后,可以访问私有属性
def say_weight(self, girl_weight):
if girl_weight > 50:
print('体重大于50kg')
else:
print('体重小于50kg')
# 方法
def say(self):
print('说话的方法')
# 私有方法:在方法名前面加两个下划线
def __say_private(self):
print('私有方法')
# 在类的内部可以调用私有方法,一般会设置限定条件,若条件满足,则调用私有方法
def call_private(self, relation):
if relation == 'friend':
self.__say_private()
else:
print('不是朋友,不能访问私有方法')
# 创建对象
girl = Girl('小明', 18, 170)
# 通过对象访问属性(公有属性)
print(girl.name) # 小明
print(girl.age) # 18
print(girl.height) # 170
# 通过对象访问方法(公有属性)
girl.say() # 说话的方法
# 私有属性:在类的外部不能直接访问
# print(girl.__weight)
# 通过公开的对外的方法,传入条件,条件满足能访问到私有属性
girl.say_weight(60) # 体重大于50kg
girl.say_weight(40) # 体重小于50kg
# 私有方法:在类的外部不能直接访问
# girl.__say_private()
# 通过公开的对外的方法,传入条件,条件满足能访问到私有方法
girl.call_private('friend') # 私有方法
girl.call_private('stranger') # 不是朋友,不能访问私有方法
91-get和set访问和设置私有属性和私有方法
# get和set 不是系统的函数,而是自己定义的;为了和面向对象封装的概念相吻合
# 一般对外公开的方法会设置为get.....,set.....
# 定义类
class Girl():
# 构造函数
def __init__(self, name, age):
self.name = name
# 设置私有属性 __age
self.__age = 18
# 通过get函数获取私有属性;命名规则:get+私有属性名(私有属性名首字母大写)
def getAge(self, name):
if name != self.name:
print('你没有权限')
else:
print(self.__age, '岁')
# # 通过set函数设置私有属性;命名规则:set+私有属性名(私有属性名首字母大写)
def setAge(self, age, name):
if name != self.name:
print('你没有权限')
else:
self.__age = age
# 方法
def run(self):
print(self.name, '正在跑步...')
# 创建对象
girl = Girl('小明', 18)
girl.run() # 小明正在跑步...
# 在类的外部通过访问getAge函数,获取私有属性
girl.getAge('小明') # 18
girl.getAge('方式') # 你没有权限
# 在类的外部通过访问setAge函数,设置私有属性
girl.setAge(20, '小明') # 20
girl.getAge('小明') # 20
girl.setAge(22, '方式') # 你没有权限
92-装饰器访问和设置私有属性
# 定义类
class Girl():
# 构造函数
def __init__(self, name, age):
self.name = name
# __age为私有属性
self.__age = age
# 方法
def run(self):
print(self.name, '正在跑步...')
# 装饰器@property访问私有属性,等同于getAge()
@property
def age(self):
print(self.__age, '年') # 18
# 装饰器设置私有属性,@ + 属性名 + setter,等同于setAge()
@age.setter
def age(self, age):
self.__age = age
print('设置年龄为:', age)
# 创建对象
girl = Girl('小明', 18)
girl.run() # 小明正在跑步...
girl.age # 18,通过装饰器访问类的私有属性
girl.age = 20 # 通过装饰器设置类的私有属性
girl.age # 设置年龄为: 20
93-面向对象单继承
# 面向对象的三大概念:封装、继承、多态
'''
继承:
如果两个或者两个以上的类有相同的属性和方法,我们可以抽取出一个类来,
在抽取的类中声明公共的部分,被抽取出来的类叫做父类\基类\根类, 两个或两个以上的类叫做子类\派生类.
'''
'''
1.在Python中,object是所有类的父类,如果一个类没有明确父类,Python就默认父类是object。
2.使用继承,简化代码,提高代码的复用性。
'''
# 单继承:只有一个父类
# 定义父类
class Animal(object):
# 方法
def say(self):
print('父类的方法')
# 定义子类:只需要将父类的名称写到子类名称的后面的小括号中,就可以实现子类对父类的继承
class Dog(Animal):
def eat(self):
print('子类的方法')
# 创建子类对象
dog = Dog() # 子类对象
dog.say() # 父类的方法
dog.eat() # 子类的方法
94-构造函数的继承
# 定义父类
class Animal(object):
# 构造函数
def __init__(self, name, sex):
self.name = name
self.sex = sex
# 方法
def eat(self):
print('所以得动物都有捕获猎物的技能')
# 定义子类:只需要将父类的名称写到子类名称的后面的小括号中,就可以实现子类对父类的继承
class Dog(Animal):
# 构造函数
def __init__(self, name, sex, tail):
# 第一种方法:子类继承父类的属性
# Animal.__init__(self, name, sex) # 子类可以重写父类的方法
# 第二种方法:子类继承父类的属性
super(Dog, self).__init__(name, sex) # super()函数可以调用父类的方法
# 子类定义自己的属性
self.tail = tail #
# 方法
def say(self):
print('汪汪汪.....')
# 创建子类对象
dog = Dog('八', '公', '长')
print(dog.name) # 八
print(dog.sex) # 公
print(dog.tail) # 长
dog.eat() # 所以得动物都有捕获猎物的技能
dog.say() # 汪汪汪.....
95-多继承
# 多继承:一个子类继承多个父类
# 定义父类
class Father(object):
# 构造函数
def __init__(self, surname):
self.surname = surname
# 方法
def make_money(self):
print('工作挣钱......')
# 定义母亲类
class Mother(object):
# 构造函数
def __init__(self, talent):
self.talent = talent
# 方法
def study_hard(self):
print('努力学习......')
# 定义子类:继承父类和母亲类
class Son(Father, Mother):
# 构造函数
def __init__(self, name, surname, talent):
# 调用父类构造函数
Father.__init__(self, surname)
# 调用母亲类构造函数
Mother.__init__(self, talent)
# 定义子类属性
self.name = name
# 方法
def play_game(self):
print('打游戏......')
# 创建子类对象
son = Son('小明', '王', '打游戏') # 子类对象
print(son.name) # 小明,访问子类属性
print(son.surname) # 王,访问父类属性
print(son.talent) # 打游戏,访问母亲类属性
son.make_money() # 工作挣钱......
son.study_hard() # 学习努力......
'''
总结:
1.子类可以继承父类的非私有属性和非私有方法
2.子类不可以继承父类的私有属性和私有方法
3.父类不能调用子类中的方法
继承的优缺点:
优点:
1.简化代码
2.提高代码的复用性
3.提高代码的可维护性
4.继承是多态的前提
缺点:
1.继承会导致代码的关联度偏高:
'''
96-多态
# 多态:父类引用子类对象
# 定义父类
class Animal(object):
def eat(self):
print('吃吃吃')
class Fish(Animal):
def eat(self):
print('鱼吃鱼')
class Cat(Animal):
def eat(self):
print('猫吃猫')
class Dog(Animal):
def eat(self):
print('狗吃狗')
# 创建子类对象
fish = Fish() # 创建一个Fish对象
cat = Cat() # 创建一个Cat对象
dog = Dog() # 创建一个Dog对象
# 各个不同的子类对象,调用相同名字的eat方法
fish.eat() # 输出:鱼吃鱼
cat.eat() # 输出:猫吃猫
dog.eat() # 输出:狗吃狗
# 严格意义上的多态体现
class Person(object):
def feed(self, animal):
animal.eat()
person = Person() # 创建一个Person对象
person.feed(cat) # 输出:猫吃猫
person.feed(dog) # 输出:狗吃狗
person.feed(fish) # 输出:鱼吃鱼
97-引入正则表达式
# 封装函数判断手机号码是否合法
def is_valid_phone_number(phone_number):
if len(phone_number) != 11:
print("手机号码长度不正确")
return
if phone_number[0] != '1':
print("手机号码格式不正确")
return
if not phone_number.isdigit(): # 判断是否为数字
print("手机号码格式不正确")
return
print("手机号码格式正确")
is_valid_phone_number("12345678901") # 输出:手机号码格式正确
# 使用正则表达式
import re
result = re.search("^1[3456789]\d{9}$", "13345678901") # 输出:None
if result:
print("手机号码格式正确")
else:
print("手机号码格式不正确")
98-正则表达式常用函数
'''
正则表达式:是一个特殊的字符序列,计算机科学的一个概念,主要用来检索\替换那些符合该序列的文本
在python中使用正则表达式,主要是借助re模块来实现.
特点:
1.灵活性、功能性、逻辑性强
2.可以使用简单的方法实现字符串的复杂处理
3.对于刚接触的人有些难度
优点:
1.爬虫
2.文本处理
3.数据校验
'''
import re
# \d: 表示0-9的数字
# +: 表示前面的字符出现一次或多次
'''
re.match(正则表达式, 要验证的字符串, 正则表达式修饰符(可选参数))
作用:匹配字符串的指定内容,匹配成功返回对象,匹配失败返回None
'''
print(re.match('\d+', '123456sadg')) # <_sre.Match object; span=(0, 6), match='123456'>
print(re.match('\d+', 'sadg')) # None
'''
re.search(正则表达式, 要验证的字符串, 正则表达式修饰符(可选参数))
作用:匹配字符串是否包含指定内容,匹配成功返回对象,匹配失败返回None
'''
print(re.search('\d+', '123456sadg')) # <_sre.Match object; span=(0, 6), match='123456'>
print(re.search('\d+', 'sadg7864')) # <_sre.Match object; span=(3, 9), match='7864'>
print(re.search('\d+', 'sadg9856sdfdg')) # <_sre.Match object; span=(3, 9), match='9856'>
print(re.search('\d+', 'sadg')) # None
'''
re.findall(正则表达式, 要验证的字符串)
作用:返回一个列表,列表中包含所有匹配到的字符串
'''
print(re.findall('\d+', 'sadg7864arf8956awets8656awtesr')) # ['7864', '8956', '8656']
print(re.findall('\d+', 'sadg')) # []
99-正则表达式匹配单个字符
import re
'''
匹配单个字符
.:表示除了换行之外的字符 \n
[]: 表示的是范围
-:表示的是区间
[0123456789]:表示匹配[]中的任意一个字符
[a-z]:表示匹配小写字母a-z之问的任意一个字母
[A-Z]: 表示匹配大写字母A-Z之间的任意一个字母
[0-9a-zA-Z]: 表示匹配任意的数字和字母
[^0-9]: 表示匹配任意一个非数字字符
\d:表示匹配任意的数字等同于[0-9]
\D:表示对\d进行取反,表示匹配任意的非数字字符 等同于[^0-9]
\w:表小匹配任意的数字 字厅 下划线 等同于[0-9a-zA-Z ]
\W:表示对\w进行取反,匹配除了数字 字母 下划线之外的仟意字符
\s:表示匹配任意的空白符(空格 换行 回车 换贞 制表符)
\S:表示对\s进行取反.
'''
print(re.search('.', 'abc123')) # <_sre.SRE_Match object; span=(0, 1), match='a'>
print(re.search('he[asdf]llo', 'heallo')) # <_sre.SRE_Match object; span=(0, 5), match='hello'>
print(re.search('he[asdf]llo', 'hemllo')) # None
print(re.search('he[0-9]llo', 'he2llo')) # <re.Match object; span=(0, 6), match='he2llo'>
print(re.search('he[0-9]llo', 'he234llo')) # None
print(re.search('he\dllo', 'he5llo')) # <re.Match object; span=(0, 5), match='he5llo'>
print(re.search('he\Dllo', 'he4llo')) # None
print(re.search('he\Dllo', 'heallo')) # <re.Match object; span=(0, 5), match='heallo'>
print(re.search('he[a-z]llo', 'hewllo')) # <re.Match object; span=(0, 5), match='hewllo'>
print(re.search('he[A-Z]llo', 'heAllo')) # <re.Match object; span=(0, 6), match='heAllo'>
print(re.search('he[^a-z]llo', 'he1llo')) # <re.Match object; span=(0, 5), match='he1llo'>
print(re.search('he\wllo', 'he5llo')) # <re.Match object; span=(0, 5), match='he5llo'>
print(re.search('he\wllo', 'heKllo')) # <re.Match object; span=(0, 5), match='heKllo'>
print(re.search('he\wllo', 'heFllo')) # <re.Match object; span=(0, 5), match='heFllo'>
print(re.search('he\wllo', 'he_llo')) # <re.Match object; span=(0, 6), match='he_llo'>
print(re.search('he\wllo', 'he%llo')) # None
print(re.search('he\Wllo', 'he%llo')) # <re.Match object; span=(0, 6), match='he%llo'>
print(re.search('he\Wllo', 'he5llo')) # None
print(re.search('he\Wllo', 'hevllo')) # None
print(re.search('he\Wllo', 'heLllo')) # None
print(re.search('he\Wllo', 'he_llo')) # None
100-正则表达式匹配多个字符
"""
?:表示匹配前面的字符出现0次或1次
+:表示匹配前面的字符出现1次或多次
*:表示匹配前面的字符出现0次或多次
{}:表示匹配前面的字符出现指定的次数或者出现在指定范围的次数
{4}:表示{}前面的字符只能出现4次
{4,7}:表示{} 前面的字符只能出现4次至7次
{4,}:表示前面的字符至少可以出现4次
{,7}:表示前的字符最多可以出现7次.
"""
import re
print(re.search('face?book', 'facebook')) # 出现1次
print(re.search('face?book', 'facbook')) # 出现0次
print(re.search('face?book', 'faceeeeebook')) # None
print(re.search('face+book', 'facebook')) # 出现1次
print(re.search('face+book', 'faceeeeeebook')) # 出现多次
print(re.search('face*book', 'facebook')) # 出现0次
print(re.search('face*book', 'faceeeeeebook')) # 出现多次
print(re.search('face{4}book', 'faceeeebook')) # 出现4次
print(re.search('face{4}book', 'faceebook')) # None
print(re.search('face{4,}book', 'faceeeeeebook')) # 出现至少4次
print(re.search('face{4,8}book', 'faceeeeeebook')) # 指定范围出现4-8次
print(re.search('face{4,8}book', 'faceeeeeeeeebook')) # None
print(re.search('face{4,8}book', 'faceebook')) # None
print(re.search('face{,8}book', 'faceeeeeeeebook')) # 出现8次或更少
print(re.search('face{,8}book', 'faceeeeeeeeebook')) # None
101-正则表达式模式修正符
# 模式修正符:主要用于修饰正则表达式
"""
re.s:表示可以让正则表达式匹配换行。 \n表示换行
re.I:表示可以让正则表达式忽略宁母大小写
.:表示匹配除了换行之外的任意宁符
"""
import re
print(re.search('chengdu.', 'chengdu123jkl')) #
print(re.search('chengdu.', 'chengdufffff123'))
print(re.search('chengdu.', 'chengdu\n')) # 匹配不到None
print(re.search('chengdu.', 'chengdu\n', re.S)) # 'chengdu\n'
print(re.search('chengdu[a-z]', 'chengdukkkkkk')) # 'chengduk'
print(re.search('chengdu[a-z]', 'chengduLLLL')) # None
print(re.search('chengdu[a-z]', 'chengduLLLL', re.I)) # 'chengduL'
102-正则表达式边界字符
import re
"""
^ : 行首匹配(以指定字符开头)和[^] 不是一个意思
$ : 行尾匹配(以指定字符结束)
^文本$ : 精准匹配
"""
print(re.search("^world", 'world'))
print(re.search("^world", 'hello')) # None
print(re.search("world$", 'world'))
print(re.search("world$", 'hello')) # None
print(re.search("^world$", 'world')) #
print(re.search("^world$", 'hello')) # None
103-正则表达式匹配分组
import re
# ():表示一个整体,表示分组,然后捕获
tel = "0010-12345678"
# 定义正则表达式
pattern = '(\d{4})-(\d{8})'
result = re.match(pattern, tel)
print(result) # <re.Match object; span=(0, 13), match='0010-12345678'>
print(result.group()) # 0010-12345678
print(result.group(1)) # 0010
print(result.group(2)) # 12345678
print(result.groups()) # ('0010', '12345678')
104--正则表达式其他功能函数
import re
"""
\ : 表示转义字符,让正则表达式中的字符失去原有的意义
. :表示匹配除了换行之外的任意字符, \.就代表一个普通的符号,而不是正则表达式中的。
"""
print(re.search('goog\.le', 'goog.le')) # <_sre.SRE_Match object; span=(0, 6), match='goog.le'>
# | :表示或者. 正则表达式1 | 正则表达式2 | 正则表达式3, 只要满足其中一个正则表达式即可
print(re.search('as|df|gh', '123as456')) # <_sre.SRE_Match object; span=(3, 5), match='as'>
print(re.search('as|df|gh', '123df456')) # <_sre.SRE_Match object; span=(3, 5), match='df'>
# re.compile()表示编译正则表达式,用于提高正则匹配的效率
str_1 = '010-123as456'
# 定义正则表达式,使用 re.compile()编译
pattern = re.compile('(\d{3})-(\d{8})')
print(pattern.search(str_1)) # <_sre.SRE_Match object; span=(0, 13), match='010-123as456'>
# re.split() 将字符串按照正则表达式分割
print(re.split('\d', 'as123df456ghj789')) # ['as', '', '', 'df', '', '', 'ghj', '', '', '']
# re.sub() re.subn() 将字符串按照正则表达式替换
str_2 = '娃娃 热风 热水 二十个果然是,挖方 扔收入 饿死狗头人.....'
print(re.sub('\s+', '***', str_2)) # 娃娃***热风***热水***二十个果然是,挖方***扔收入***饿死狗头人.....
print(re.subn('\s+', '***', str_2)) # ('娃娃***热风***热水***二十个果然是,挖方***扔收入***饿死狗头人.....', 5)
# 正则表达式匹配中文
chinese = "[\u4e00-\u9fa5]+"
print(re.search(chinese, 'hello 你好 welcome 欢迎光临....')) # <_sre.SRE_Match object; span=(2, 3), match='你好'>
105-错误和异常
1.错误:通常是指程序中的语法错误或逻辑错误。
2.异常:python程序的语法是正确的,在运行的过程中出现了问题,运行期间检测到的错误被称为异常。 大多数的异常都不会被程序处理,都是以错误信息的形式展现。
异常常见的解决方案:捕获异常和抛出异常
106-捕获异常
# 捕获异常
# 第一种捕获方式:try...except...
try: # 尝试执行程序
print(1/0)
except ZeroDivisionError: # 捕获异常
print('除数不能为0')
# 第二种捕获方式:try...except
try:
num = 20/0
print(num)
except Exception as e: # 捕获异常
print('捕获异常')
print(e) # division by zero
# 第三种捕获方式:try...except...else
'''
总结:
1.try-except-else这个结构类似于 if-elif-elif...-else
2.try-except-else中的else可有可无
3.执行流程:首先会执行try结构中的程序,如果try中的语句没有异常,则直接跳过所有的except语句,执行else语句,如果try中的语句有异常,则取except结构中去匹配错误,如果匹配到了则执行里面的语句。
'''
# 没有捕获异常
try:
num = 45 / 15
print(num) # 可能存在异常程序
except Exception as e:
print('捕获异常')
else:
print('没有捕获异常')
# 有捕获异常
try:
num = 45 / 0
print(num) # 可能存在异常程序
except Exception as e:
print('捕获异常')
print(e) # division by zero
else:
print('没有捕获异常')
# 第四种捕获方式:try...except..finally
'''
执行流程:不管try中的语句是否存在异常,也不管except有没有捕获到异常,finally语句都会执行
'''
# 没有捕获异常
try:
num = 45 / 3
print(num)
except Exception as e:
print('捕获异常')
print(e)
finally:
print('finally')
# 有捕获异常
try:
num = 45 / 0
print(num) # 可能存在异常程序
except Exception as e:
print('捕获异常')
print(e) # division by zero
finally:
print('finally')
107-抛出异常
# 抛出异常:自己根据情况定义异常信息,进行手动抛出
try:
num = input('请输入数字:')
# 输入非数字,抛出异常
if not num.isdigit():
raise ValueError('输入非数字') # 手动抛出异常
else:
print('输入数字:', num)
except Exception as e:
print('捕获异常信息:', repr(e))
108-自定义异常
"""
1.自己定义的异常类:必须继承自Exception
2.自定义异常类中的 构造函数,定义属性保存异常信息、,
3.重写__str__ 函数,打印异常的信息
"""
# 自定义异常类
class MyException(Exception): # 自定义异常类(继承自Exception)
def __init__(self, value): # 构造函数
self.value = value
def __str__(self): # 重写__str__函数
if self.value == 0:
return "除数不能是0"
# 自定义方法
def get_data(num):
try:
if num == 0:
exc = MyException(num)
print(exc)
else:
print(10 / num)
except Exception as e:
pass
# 调用自定义方法
get_data(5) # 2
get_data(0) # 除数不能是0