类
定义操作
# 1. 定义类class Washer():def wash(self):print('我会洗⾐服')def print_info(self):# 类⾥⾯获取实例属性print(f'haier1洗⾐机的宽度是{self.width}')print(f'haier1洗⾐机的⾼度是{self.height}')# 2. 创建对象haier1 =Washer()# <__main__.Washer object at 0x0000018B7B224240>print(haier1)# haier1对象调⽤实例⽅法# 3. 添加实例属性haier1.width = 500haier1.height = 800# 4. 获取实例的对象print(f'haier1洗⾐机的宽度是{haier1.width}')print(f'haier1洗⾐机的⾼度是{haier1.height}')
魔法⽅法
在Python中, xx() 的函数叫做魔法⽅法,指的是具有特殊功能的函数
1. init()
注意
init() ⽅法,在创建⼀个对象时默认被调⽤,不需要⼿动调⽤
init(self) 中的self参数,不需要开发者传递,python解释器会⾃动把当前的对象引⽤传递过去。
class Washer():# 定义初始化功能的函数def __init__(self):# 添加实例属性self.width = 500self.height = 800def print_info(self):# 类⾥⾯调⽤实例属性print(f'洗⾐机的宽度是{self.width}, ⾼度是{self.height}')haier1 = Washer()haier1.print_info()
2.带参数的init()
⼀个类可以创建多个对象,传参数对不同的对象设置不同的初始化属性
class Washer():def __init__(self, width, height):self.width = widthself.height = heightdef print_info(self):print(f'洗⾐机的宽度是{self.width}')print(f'洗⾐机的⾼度是{self.height}')haier1 = Washer(10, 20)haier1.print_info()haier2 = Washer(30, 40)haier2.print_info()
3. str__()
当使⽤print输出对象的时候,默认打印对象的内存地址。如果类定义了 str ⽅法,那么就会打印从在这个⽅法中 return 的数据。
class Washer():def __init__(self, width, height):self.width = widthself.height = heightdef __str__(self):return '这是海尔洗⾐机的说明书'haier1 = Washer(10, 20)# 这是海尔洗⾐机的说明书print(haier1)
4.del()
当删除对象时,python解释器也会默认调⽤ del() ⽅法。
class Washer():def __init__(self, width, height):self.width = widthself.height = heightdef __del__(self):print(f'{self}对象已经被删除')haier1 = Washer(10, 20)# <__main__.Washer object at 0x0000026118223278>对象已经被删除del haier1
总结
- 类
- 创建类
class 类名():代码
- 对象
对象名 = 类名()
- 添加对象属性
- 类外面
对象名.属性名 = 值
- 类⾥⾯
self.属性名 = 值
- 获取对象属性
- 类外面
对象名.属性名
- 类⾥⾯
self.属性名
- 魔法方法
- init_() : 初始化
- str__() :输出对象信息
- del() :删除对象时调⽤
继承
单继承
# 1. 师⽗类class Master(object):def __init__(self):self.kongfu = '[古法煎饼果⼦配⽅]'def make_cake(self):print(f'运⽤{self.kongfu}制作煎饼果⼦')# 2. 徒弟类class Prentice(Master):pass# 3. 创建对象daqiudaqiu = Prentice()# 4. 对象访问实例属性print(daqiu.kongfu)# 5. 对象调⽤实例⽅法daqiu.make_cake()
多继承
class Master(object):def __init__(self):self.kongfu = '[古法煎饼果⼦配⽅]'def make_cake(self):print(f'运⽤{self.kongfu}制作煎饼果⼦')# 创建学校类class School(object):def __init__(self):self.kongfu = '[⿊⻢煎饼果⼦配⽅]'def make_cake(self):print(f'运⽤{self.kongfu}制作煎饼果⼦')class Prentice(School, Master):passdaqiu = Prentice()print(daqiu.kongfu)daqiu.make_cake()
注意:当⼀个类有多个⽗类的时候,默认使⽤第⼀个⽗类的同名属性和⽅法。
⼦类和⽗类具有同名属性和⽅法,默认使⽤⼦类的同名属性和⽅法。
⼦类调⽤⽗类的方法
class Master(object):def __init__(self):self.kongfu = '[古法煎饼果⼦配⽅]'def make_cake(self):print(f'运⽤{self.kongfu}制作煎饼果⼦')class School(object):def __init__(self):self.kongfu = '[⿊⻢煎饼果⼦配⽅]'def make_cake(self):print(f'运⽤{self.kongfu}制作煎饼果⼦')class Prentice(School, Master):def __init__(self):self.kongfu = '[独创煎饼果⼦配⽅]'def make_cake(self):# 如果是先调⽤了⽗类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调⽤属性前,先调⽤⾃⼰⼦类的初始化self.__init__()print(f'运⽤{self.kongfu}制作煎饼果⼦')# 调⽤⽗类⽅法,但是为保证调⽤到的也是⽗类的属性,必须在调⽤⽅法前调⽤⽗类的初始化def make_master_cake(self):Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)def make_cake1(self):print(f'运⽤{self.kongfu}制作煎饼果⼦')# ⽅法2.1# super(School, self).__init__()# super(School, self).make_cake()# ⽅法2.2super().__init__()super().make_cake()daqiu = Prentice()daqiu.make_cake()daqiu.make_master_cake()daqiu.make_school_cake()daqiu.make_cake()
super方法
class Prentice(School, Master):def __init__(self):self.kongfu = '[独创煎饼果⼦配⽅]'def make_cake(self):# 如果是先调⽤了⽗类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调⽤属性前,先调⽤⾃⼰⼦类的初始化self.__init__()print(f'运⽤{self.kongfu}制作煎饼果⼦')# 调⽤⽗类⽅法,但是为保证调⽤到的也是⽗类的属性,必须在调⽤⽅法前调⽤⽗类的初始化def make_master_cake(self):Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)def make_cake1(self):print(f'运⽤{self.kongfu}制作煎饼果⼦')# ⽅法2.1# super(School, self).__init__()# super(School, self).make_cake()# ⽅法2.2super().__init__()super().make_cake()# ⼀次性调⽤⽗类的同名属性和⽅法# 注意:使⽤super() 可以⾃动查找⽗类。调⽤顺序遵循 __mro__ 类属性的顺序。⽐较适合单继承使⽤。def make_old_cake(self):# ⽅法⼀:代码冗余;⽗类类名如果变化,这⾥代码需要频繁修改# Master.__init__(self)# Master.make_cake(self)# School.__init__(self)# School.make_cake(self)# ⽅法⼆: super()# ⽅法2.1 super(当前类名, self).函数()# super(Prentice, self).__init__()# super(Prentice, self).make_cake()# ⽅法2.2 super().函数()super().__init__()super().make_cake()
私有权限
在Python中,可以为实例属性和⽅法设置私有权限,即设置某个实例属性或实例⽅法不继承给⼦类。
设置私有权限的⽅法:在属性名和⽅法名 前⾯ 加上两个下划线 __
私有属性和私有⽅法只能在类⾥⾯访问和修改。
在Python中,⼀般定义函数名 get_xx ⽤来获取私有属性,定义 set_xx⽤来修改私有属性值。
class Master(object):def __init__(self):self.kongfu = '[古法煎饼果⼦配⽅]'def make_cake(self):print(f'运⽤{self.kongfu}制作煎饼果⼦')class School(object):def __init__(self):self.kongfu = '[⿊⻢煎饼果⼦配⽅]'def make_cake(self):print(f'运⽤{self.kongfu}制作煎饼果⼦')class Prentice(School, Master):def __init__(self):self.kongfu = '[独创煎饼果⼦配⽅]'# 定义私有属性self.__money = 2000000# 定义私有⽅法def __info_print(self):print(self.kongfu)print(self.__money)def make_cake(self):self.__init__()print(f'运⽤{self.kongfu}制作煎饼果⼦')def make_master_cake(self):Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)# 徒孙类class Tusun(Prentice):passdaqiu = Prentice()# 对象不能访问私有属性和私有⽅法# print(daqiu.__money)# daqiu.__info_print()xiaoqiu = Tusun()# ⼦类⽆法继承⽗类的私有属性和私有⽅法# print(xiaoqiu.__money) # ⽆法访问实例属性__money# xiaoqiu.__info_print()
总结
- 继承的特点
- ⼦类默认拥有⽗类的所有属性和⽅法
- ⼦类重写⽗类同名⽅法和属性
- ⼦类调⽤⽗类同名⽅法和属性
- super()⽅法快速调⽤⽗类⽅法
- 私有权限
- 不能继承给⼦类的属性和⽅法需要添加私有权限
- 语法
class 类名():# 私有属性__属性名 = 值# 私有⽅法def __函数名(self):代码
多态
类属性
- 类属性就是 类对象 所拥有的属性,它被 该类的所有实例对象 所共有。
- 类属性可以使⽤ 类对象 或 实例对象 访问
类属性的优点
- 类的实例 记录的某项数据 始终保持⼀致时,则定义类属性。
- 实例属性要求每个对象为其 单独开辟⼀份内存空间 来记录数据,⽽ 类属性 为全类所共有,仅占⽤⼀份内存,更加节省内存空间。
## 类属性和实例属性class Dog(object):tooth = 10wangcai = Dog()xiaohei = Dog()print(Dog.tooth) # 10print(wangcai.tooth) # 10print(xiaohei.tooth) # 10
修改类属性
类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了⼀个实例属性。
class Dog(object):tooth = 10wangcai = Dog()xiaohei = Dog()# 修改类属性Dog.tooth = 12print(Dog.tooth) # 12print(wangcai.tooth) # 12print(xiaohei.tooth) # 12# 不能通过对象修改属性,如果这样操作,实则是创建了⼀个实例属性wangcai.tooth = 20print(Dog.tooth) # 12print(wangcai.tooth) # 20print(xiaohei.tooth) # 12
实例属性
class Dog(object):def __init__(self):self.age = 5def info_print(self):print(self.age)wangcai = Dog()print(wangcai.age) # 5# print(Dog.age) # 报错:实例属性不能通过类访问wangcai.info_print() # 5
类⽅法和静态⽅法
类⽅法特点
- 第⼀个形参是类对象的⽅法
- 需要⽤装饰器 @classmethod 来标识其为类⽅法,对于类⽅法, 第⼀个参数必须是类对象,⼀般以cls 作为第⼀个参数。
类⽅法使⽤场景
- 当⽅法中 需要使⽤类对象 (如访问私有类属性等)时,定义类⽅法
- 类⽅法⼀般和类属性配合使⽤
class Dog(object):__tooth = 10@classmethoddef get_tooth(cls):return cls.__toothwangcai = Dog()result = wangcai.get_tooth()print(result) # 10
静态⽅法
静态⽅法特点
- 需要通过装饰器 @staticmethod 来进⾏修饰, 静态⽅法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)。
- 静态⽅法 也能够通过 实例对象 和 类对象 去访问。
静态⽅法使⽤场景
- 当⽅法中 既不需要使⽤实例对象(如实例对象,实例属性),也不需要使⽤类对象 (如类属性、类⽅法、创建实例等)时,定义静态⽅法
- 取消不需要的参数传递,有利于 减少不必要的内存占⽤和性能消耗
class Dog(object):@staticmethoddef info_print():print('这是⼀个狗类,⽤于创建狗实例....')wangcai = Dog()# 静态⽅法既可以使⽤对象访问⼜可以使⽤类访问wangcai.info_print()Dog.info_print()
总结
类⽅法
@classmethoddef xx():代码
静态⽅法
@staticmethoddef xx():代码
异常
常规写法
try:可能发⽣错误的代码except:如果出现异常执⾏的代码## 常规写法try:print(num)except NameError:print('有错误')## 捕获异常描述信息try:print(num)except (NameError, ZeroDivisionError) as result:print(result)## 捕获所有异常try:print(num)except Exception as result:print(result)## 异常的else## else表示的是如果没有异常要执⾏的代码。try:print(1)except Exception as result:print(result)else:print('我是else,是没有异常的时候执⾏的代码')## 异常的finally## finally表示的是⽆论是否异常都要执⾏的代码,例如关闭⽂件try:f = open('test.txt', 'r')except Exception as result:f = open('test.txt', 'w')else:print('没有异常,真开⼼')finally:f.close()
异常的传递
import timetry:f = open('test.txt')try:while True:content = f.readline()if len(content) == 0:breaktime.sleep(2)print(content)except:# 如果在读取⽂件的过程中,产⽣了异常,那么就会捕获到# ⽐如 按下了 ctrl+cprint('意外终⽌了读取数据')finally:f.close()print('关闭⽂件')except:print("没有这个⽂件")
⾃定义异常
在Python中,抛出⾃定义异常的语法为 raise 异常类对象 。
# ⾃定义异常类,继承Exceptionclass ShortInputError(Exception):def __init__(self, length, min_len):self.length = lengthself.min_len = min_len# 设置抛出异常的描述信息def __str__(self):return f'你输⼊的⻓度是{self.length}, 不能少于{self.min_len}个字符'def main():try:con = input('请输⼊密码:')if len(con) < 3:raise ShortInputError(len(con), 3)except Exception as result:print(result)else:print('密码已经输⼊完成')main()
总结
## 异常语法try:可能发⽣异常的代码except:如果出现异常执⾏的代码else:没有异常执⾏的代码finally:⽆论是否异常都要执⾏的代码## 捕获异常except 异常类型:代码except 异常类型 as xx:代码## ⾃定义异常# 1. ⾃定义异常类class 异常类类名(Exception):代码# 设置抛出异常的描述信息def __str__(self):return ...# 2. 抛出异常raise 异常类名()# 捕获异常except Exception...
模块和包
模块
Python 模块(Module),是⼀个 Python ⽂件,以 .py 结尾,包含了 Python 对象定义和Python语句。
模块能定义函数,类和变量,模块⾥也能包含可执⾏的代码。
导⼊模块的⽅式
- import 模块名
- from 模块名 import 功能名
- from 模块名 import *
- import 模块名 as 别名
- from 模块名 import 功能名 as 别名
### import# 1. 导⼊模块import 模块名import 模块名1, 模块名2...# 2. 调⽤功能模块名.功能名()## from..import..from 模块名 import 功能1, 功能2, 功能3...from math import sqrtprint(sqrt(9))## from .. import *from 模块名 import *from math import *print(sqrt(9))### as定义别名# 模块定义别名import 模块名 as 别名# 功能定义别名from 模块名 import 功能 as 别名
制作模块
每个Python⽂件都可以作为⼀个模块,模块的名字就是⽂件的名字。也就是说⾃定义模块名必须要符合标识符命名规则。
## 新建⼀个Python⽂件,命名为 my_module1.py ,并定义 testA 函数。def testA(a, b):print(a + b)# 只在当前⽂件中调⽤该函数,其他导⼊的⽂件内不符合该条件,则不执⾏testA函数调⽤if __name__ == '__main__':testA(1, 1)## 调⽤模块import my_module1my_module1.testA(1, 1)
注意
- 如果使⽤ from .. import .. 或 from .. import * 导⼊多个模块的时候,且模块内有同名功能。当调⽤这个同名功能的时候,调⽤到的是后⾯导⼊的模块的功能。
all
如果⼀个模块⽂件中有 all 变量,当使⽤ from xxx import * 导⼊时,只能导⼊这个列表中的元素。
__all__ = ['testA']def testA():print('testA')def testB():print('testB')## 导⼊模块的⽂件代码from my_module1 import *testA()testB()
包
包将有联系的模块组织在⼀起,即放到同⼀个⽂件夹下,并且在这个⽂件夹创建⼀个名字为 init.py ⽂件,那么这个⽂件夹就称之为包。
新建包
[New] — [Python Package] — 输⼊包名 — [OK] — 新建功能模块(有联系的模块)。
注意:新建包后,包内部会⾃动创建 init.py ⽂件,这个⽂件控制着包的导⼊⾏为。
- 新建包 mypackage
- 新建包内模块: my_module1 和 my_module2
- 模块内代码如下
# my_module1print(1)def info_print1():print('my_module1')# my_module2print(2)def info_print2():print('my_module2')
导⼊包
## import 包名.模块名## 包名.模块名.⽬标import my_package.my_module1my_package.my_module1.info_print1()## 必须在 __init__.py ⽂件中添加 __all__ = [] ,控制允许导⼊的模块列表。from my_package import *my_module1.info_print1()
