定义操作

  1. # 1. 定义类
  2. class Washer():
  3. def wash(self):
  4. print('我会洗⾐服')
  5. def print_info(self):
  6. # 类⾥⾯获取实例属性
  7. print(f'haier1洗⾐机的宽度是{self.width}')
  8. print(f'haier1洗⾐机的⾼度是{self.height}')
  9. # 2. 创建对象
  10. haier1 =Washer()
  11. # <__main__.Washer object at 0x0000018B7B224240>
  12. print(haier1)
  13. # haier1对象调⽤实例⽅法
  14. # 3. 添加实例属性
  15. haier1.width = 500
  16. haier1.height = 800
  17. # 4. 获取实例的对象
  18. print(f'haier1洗⾐机的宽度是{haier1.width}')
  19. print(f'haier1洗⾐机的⾼度是{haier1.height}')

魔法⽅法

在Python中, xx() 的函数叫做魔法⽅法,指的是具有特殊功能的函数

1. init()

注意

init() ⽅法,在创建⼀个对象时默认被调⽤,不需要⼿动调⽤

init(self) 中的self参数,不需要开发者传递,python解释器会⾃动把当前的对象引⽤传递过去。

  1. class Washer():
  2. # 定义初始化功能的函数
  3. def __init__(self):
  4. # 添加实例属性
  5. self.width = 500
  6. self.height = 800
  7. def print_info(self):
  8. # 类⾥⾯调⽤实例属性
  9. print(f'洗⾐机的宽度是{self.width}, ⾼度是{self.height}')
  10. haier1 = Washer()
  11. haier1.print_info()

2.带参数的init()

⼀个类可以创建多个对象,传参数对不同的对象设置不同的初始化属性

  1. class Washer():
  2. def __init__(self, width, height):
  3. self.width = width
  4. self.height = height
  5. def print_info(self):
  6. print(f'洗⾐机的宽度是{self.width}')
  7. print(f'洗⾐机的⾼度是{self.height}')
  8. haier1 = Washer(10, 20)
  9. haier1.print_info()
  10. haier2 = Washer(30, 40)
  11. haier2.print_info()

3. str__()

当使⽤print输出对象的时候,默认打印对象的内存地址。如果类定义了 str ⽅法,那么就会打印从在这个⽅法中 return 的数据。

  1. class Washer():
  2. def __init__(self, width, height):
  3. self.width = width
  4. self.height = height
  5. def __str__(self):
  6. return '这是海尔洗⾐机的说明书'
  7. haier1 = Washer(10, 20)
  8. # 这是海尔洗⾐机的说明书
  9. print(haier1)

4.del()

当删除对象时,python解释器也会默认调⽤ del() ⽅法。

  1. class Washer():
  2. def __init__(self, width, height):
  3. self.width = width
  4. self.height = height
  5. def __del__(self):
  6. print(f'{self}对象已经被删除')
  7. haier1 = Washer(10, 20)
  8. # <__main__.Washer object at 0x0000026118223278>对象已经被删除
  9. del haier1

总结

    • 创建类
  1. class 类名():
  2. 代码
  • 对象
  1. 对象名 = 类名()
  • 添加对象属性
    • 类外面
  1. 对象名.属性名 =
  • 类⾥⾯
  1. self.属性名 =
  • 获取对象属性
    • 类外面
  1. 对象名.属性名
  • 类⾥⾯
  1. self.属性名
  • 魔法方法
    • init_() : 初始化
    • str__() :输出对象信息
    • del() :删除对象时调⽤

继承

单继承

  1. # 1. 师⽗类
  2. class Master(object):
  3. def __init__(self):
  4. self.kongfu = '[古法煎饼果⼦配⽅]'
  5. def make_cake(self):
  6. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  7. # 2. 徒弟类
  8. class Prentice(Master):
  9. pass
  10. # 3. 创建对象daqiu
  11. daqiu = Prentice()
  12. # 4. 对象访问实例属性
  13. print(daqiu.kongfu)
  14. # 5. 对象调⽤实例⽅法
  15. daqiu.make_cake()

多继承

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果⼦配⽅]'
  4. def make_cake(self):
  5. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  6. # 创建学校类
  7. class School(object):
  8. def __init__(self):
  9. self.kongfu = '[⿊⻢煎饼果⼦配⽅]'
  10. def make_cake(self):
  11. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  12. class Prentice(School, Master):
  13. pass
  14. daqiu = Prentice()
  15. print(daqiu.kongfu)
  16. daqiu.make_cake()

注意:当⼀个类有多个⽗类的时候,默认使⽤第⼀个⽗类的同名属性和⽅法。

⼦类和⽗类具有同名属性和⽅法,默认使⽤⼦类的同名属性和⽅法。

⼦类调⽤⽗类的方法

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果⼦配⽅]'
  4. def make_cake(self):
  5. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  6. class School(object):
  7. def __init__(self):
  8. self.kongfu = '[⿊⻢煎饼果⼦配⽅]'
  9. def make_cake(self):
  10. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  11. class Prentice(School, Master):
  12. def __init__(self):
  13. self.kongfu = '[独创煎饼果⼦配⽅]'
  14. def make_cake(self):
  15. # 如果是先调⽤了⽗类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调⽤属性前,先调⽤⾃⼰⼦类的初始化
  16. self.__init__()
  17. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  18. # 调⽤⽗类⽅法,但是为保证调⽤到的也是⽗类的属性,必须在调⽤⽅法前调⽤⽗类的初始化
  19. def make_master_cake(self):
  20. Master.__init__(self)
  21. Master.make_cake(self)
  22. def make_school_cake(self):
  23. School.__init__(self)
  24. School.make_cake(self)
  25. def make_cake1(self):
  26. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  27. # ⽅法2.1
  28. # super(School, self).__init__()
  29. # super(School, self).make_cake()
  30. # ⽅法2.2
  31. super().__init__()
  32. super().make_cake()
  33. daqiu = Prentice()
  34. daqiu.make_cake()
  35. daqiu.make_master_cake()
  36. daqiu.make_school_cake()
  37. daqiu.make_cake()

super方法

  1. class Prentice(School, Master):
  2. def __init__(self):
  3. self.kongfu = '[独创煎饼果⼦配⽅]'
  4. def make_cake(self):
  5. # 如果是先调⽤了⽗类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调⽤属性前,先调⽤⾃⼰⼦类的初始化
  6. self.__init__()
  7. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  8. # 调⽤⽗类⽅法,但是为保证调⽤到的也是⽗类的属性,必须在调⽤⽅法前调⽤⽗类的初始化
  9. def make_master_cake(self):
  10. Master.__init__(self)
  11. Master.make_cake(self)
  12. def make_school_cake(self):
  13. School.__init__(self)
  14. School.make_cake(self)
  15. def make_cake1(self):
  16. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  17. # ⽅法2.1
  18. # super(School, self).__init__()
  19. # super(School, self).make_cake()
  20. # ⽅法2.2
  21. super().__init__()
  22. super().make_cake()
  23. # ⼀次性调⽤⽗类的同名属性和⽅法
  24. # 注意:使⽤super() 可以⾃动查找⽗类。调⽤顺序遵循 __mro__ 类属性的顺序。⽐较适合单继承使⽤。
  25. def make_old_cake(self):
  26. # ⽅法⼀:代码冗余;⽗类类名如果变化,这⾥代码需要频繁修改
  27. # Master.__init__(self)
  28. # Master.make_cake(self)
  29. # School.__init__(self)
  30. # School.make_cake(self)
  31. # ⽅法⼆: super()
  32. # ⽅法2.1 super(当前类名, self).函数()
  33. # super(Prentice, self).__init__()
  34. # super(Prentice, self).make_cake()
  35. # ⽅法2.2 super().函数()
  36. super().__init__()
  37. super().make_cake()

私有权限

在Python中,可以为实例属性和⽅法设置私有权限,即设置某个实例属性或实例⽅法不继承给⼦类。

设置私有权限的⽅法:在属性名和⽅法名 前⾯ 加上两个下划线 __

私有属性和私有⽅法只能在类⾥⾯访问和修改。

在Python中,⼀般定义函数名 get_xx ⽤来获取私有属性,定义 set_xx⽤来修改私有属性值。

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果⼦配⽅]'
  4. def make_cake(self):
  5. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  6. class School(object):
  7. def __init__(self):
  8. self.kongfu = '[⿊⻢煎饼果⼦配⽅]'
  9. def make_cake(self):
  10. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  11. class Prentice(School, Master):
  12. def __init__(self):
  13. self.kongfu = '[独创煎饼果⼦配⽅]'
  14. # 定义私有属性
  15. self.__money = 2000000
  16. # 定义私有⽅法
  17. def __info_print(self):
  18. print(self.kongfu)
  19. print(self.__money)
  20. def make_cake(self):
  21. self.__init__()
  22. print(f'运⽤{self.kongfu}制作煎饼果⼦')
  23. def make_master_cake(self):
  24. Master.__init__(self)
  25. Master.make_cake(self)
  26. def make_school_cake(self):
  27. School.__init__(self)
  28. School.make_cake(self)
  29. # 徒孙类
  30. class Tusun(Prentice):
  31. pass
  32. daqiu = Prentice()
  33. # 对象不能访问私有属性和私有⽅法
  34. # print(daqiu.__money)
  35. # daqiu.__info_print()
  36. xiaoqiu = Tusun()
  37. # ⼦类⽆法继承⽗类的私有属性和私有⽅法
  38. # print(xiaoqiu.__money) # ⽆法访问实例属性__money
  39. # xiaoqiu.__info_print()

总结

  • 继承的特点
    • ⼦类默认拥有⽗类的所有属性和⽅法
    • ⼦类重写⽗类同名⽅法和属性
    • ⼦类调⽤⽗类同名⽅法和属性
  • super()⽅法快速调⽤⽗类⽅法
  • 私有权限
    • 不能继承给⼦类的属性和⽅法需要添加私有权限
    • 语法
  1. class 类名():
  2. # 私有属性
  3. __属性名 =
  4. # 私有⽅法
  5. def __函数名(self):
  6. 代码

多态

类属性

  • 类属性就是 类对象 所拥有的属性,它被 该类的所有实例对象 所共有
  • 类属性可以使⽤ 类对象实例对象 访问

类属性的优点

  • 类的实例 记录的某项数据 始终保持⼀致时,则定义类属性。
  • 实例属性要求每个对象为其 单独开辟⼀份内存空间 来记录数据,⽽ 类属性 为全类所共有,仅占⽤⼀份内存更加节省内存空间
  1. ## 类属性和实例属性
  2. class Dog(object):
  3. tooth = 10
  4. wangcai = Dog()
  5. xiaohei = Dog()
  6. print(Dog.tooth) # 10
  7. print(wangcai.tooth) # 10
  8. print(xiaohei.tooth) # 10

修改类属性

类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了⼀个实例属性。

  1. class Dog(object):
  2. tooth = 10
  3. wangcai = Dog()
  4. xiaohei = Dog()
  5. # 修改类属性
  6. Dog.tooth = 12
  7. print(Dog.tooth) # 12
  8. print(wangcai.tooth) # 12
  9. print(xiaohei.tooth) # 12
  10. # 不能通过对象修改属性,如果这样操作,实则是创建了⼀个实例属性
  11. wangcai.tooth = 20
  12. print(Dog.tooth) # 12
  13. print(wangcai.tooth) # 20
  14. print(xiaohei.tooth) # 12

实例属性

  1. class Dog(object):
  2. def __init__(self):
  3. self.age = 5
  4. def info_print(self):
  5. print(self.age)
  6. wangcai = Dog()
  7. print(wangcai.age) # 5
  8. # print(Dog.age) # 报错:实例属性不能通过类访问
  9. wangcai.info_print() # 5

类⽅法和静态⽅法

类⽅法特点

  • 第⼀个形参是类对象的⽅法
  • 需要⽤装饰器 @classmethod 来标识其为类⽅法,对于类⽅法, 第⼀个参数必须是类对象,⼀般以cls 作为第⼀个参数。

类⽅法使⽤场景

  • 当⽅法中 需要使⽤类对象 (如访问私有类属性等)时,定义类⽅法
  • 类⽅法⼀般和类属性配合使⽤
  1. class Dog(object):
  2. __tooth = 10
  3. @classmethod
  4. def get_tooth(cls):
  5. return cls.__tooth
  6. wangcai = Dog()
  7. result = wangcai.get_tooth()
  8. print(result) # 10

静态⽅法

静态⽅法特点

  • 需要通过装饰器 @staticmethod 来进⾏修饰, 静态⽅法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)
  • 静态⽅法 也能够通过 实例对象类对象 去访问。

静态⽅法使⽤场景

  • 当⽅法中 既不需要使⽤实例对象(如实例对象,实例属性),也不需要使⽤类对象 (如类属性、类⽅法、创建实例等)时,定义静态⽅法
  • 取消不需要的参数传递,有利于 减少不必要的内存占⽤和性能消耗
  1. class Dog(object):
  2. @staticmethod
  3. def info_print():
  4. print('这是⼀个狗类,⽤于创建狗实例....')
  5. wangcai = Dog()
  6. # 静态⽅法既可以使⽤对象访问⼜可以使⽤类访问
  7. wangcai.info_print()
  8. Dog.info_print()

总结

类⽅法

  1. @classmethod
  2. def xx():
  3. 代码

静态⽅法

  1. @staticmethod
  2. def xx():
  3. 代码

异常

常规写法

  1. try:
  2. 可能发⽣错误的代码
  3. except:
  4. 如果出现异常执⾏的代码
  5. ## 常规写法
  6. try:
  7. print(num)
  8. except NameError:
  9. print('有错误')
  10. ## 捕获异常描述信息
  11. try:
  12. print(num)
  13. except (NameError, ZeroDivisionError) as result:
  14. print(result)
  15. ## 捕获所有异常
  16. try:
  17. print(num)
  18. except Exception as result:
  19. print(result)
  20. ## 异常的else
  21. ## else表示的是如果没有异常要执⾏的代码。
  22. try:
  23. print(1)
  24. except Exception as result:
  25. print(result)
  26. else:
  27. print('我是else,是没有异常的时候执⾏的代码')
  28. ## 异常的finally
  29. ## finally表示的是⽆论是否异常都要执⾏的代码,例如关闭⽂件
  30. try:
  31. f = open('test.txt', 'r')
  32. except Exception as result:
  33. f = open('test.txt', 'w')
  34. else:
  35. print('没有异常,真开⼼')
  36. finally:
  37. f.close()

异常的传递

  1. import time
  2. try:
  3. f = open('test.txt')
  4. try:
  5. while True:
  6. content = f.readline()
  7. if len(content) == 0:
  8. break
  9. time.sleep(2)
  10. print(content)
  11. except:
  12. # 如果在读取⽂件的过程中,产⽣了异常,那么就会捕获到
  13. # ⽐如 按下了 ctrl+c
  14. print('意外终⽌了读取数据')
  15. finally:
  16. f.close()
  17. print('关闭⽂件')
  18. except:
  19. print("没有这个⽂件")

⾃定义异常

在Python中,抛出⾃定义异常的语法为 raise 异常类对象 。

  1. # ⾃定义异常类,继承Exception
  2. class ShortInputError(Exception):
  3. def __init__(self, length, min_len):
  4. self.length = length
  5. self.min_len = min_len
  6. # 设置抛出异常的描述信息
  7. def __str__(self):
  8. return f'你输⼊的⻓度是{self.length}, 不能少于{self.min_len}个字符'
  9. def main():
  10. try:
  11. con = input('请输⼊密码:')
  12. if len(con) < 3:
  13. raise ShortInputError(len(con), 3)
  14. except Exception as result:
  15. print(result)
  16. else:
  17. print('密码已经输⼊完成')
  18. main()

总结

  1. ## 异常语法
  2. try:
  3. 可能发⽣异常的代码
  4. except:
  5. 如果出现异常执⾏的代码
  6. else:
  7. 没有异常执⾏的代码
  8. finally:
  9. ⽆论是否异常都要执⾏的代码
  10. ## 捕获异常
  11. except 异常类型:
  12. 代码
  13. except 异常类型 as xx:
  14. 代码
  15. ## ⾃定义异常
  16. # 1. ⾃定义异常类
  17. class 异常类类名(Exception):
  18. 代码
  19. # 设置抛出异常的描述信息
  20. def __str__(self):
  21. return ...
  22. # 2. 抛出异常
  23. raise 异常类名()
  24. # 捕获异常
  25. except Exception...

模块和包

模块

Python 模块(Module),是⼀个 Python ⽂件,以 .py 结尾,包含了 Python 对象定义和Python语句。

模块能定义函数,类和变量,模块⾥也能包含可执⾏的代码。

导⼊模块的⽅式

  • import 模块名
  • from 模块名 import 功能名
  • from 模块名 import *
  • import 模块名 as 别名
  • from 模块名 import 功能名 as 别名
  1. ### import
  2. # 1. 导⼊模块
  3. import 模块名
  4. import 模块名1, 模块名2...
  5. # 2. 调⽤功能
  6. 模块名.功能名()
  7. ## from..import..
  8. from 模块名 import 功能1, 功能2, 功能3...
  9. from math import sqrt
  10. print(sqrt(9))
  11. ## from .. import *
  12. from 模块名 import *
  13. from math import *
  14. print(sqrt(9))
  15. ### as定义别名
  16. # 模块定义别名
  17. import 模块名 as 别名
  18. # 功能定义别名
  19. from 模块名 import 功能 as 别名

制作模块

每个Python⽂件都可以作为⼀个模块,模块的名字就是⽂件的名字。也就是说⾃定义模块名必须要符合标识符命名规则

  1. ## 新建⼀个Python⽂件,命名为 my_module1.py ,并定义 testA 函数。
  2. def testA(a, b):
  3. print(a + b)
  4. # 只在当前⽂件中调⽤该函数,其他导⼊的⽂件内不符合该条件,则不执⾏testA函数调⽤
  5. if __name__ == '__main__':
  6. testA(1, 1)
  7. ## 调⽤模块
  8. import my_module1
  9. my_module1.testA(1, 1)

注意

  1. 如果使⽤ from .. import .. 或 from .. import * 导⼊多个模块的时候,且模块内有同名功能。当调⽤这个同名功能的时候,调⽤到的是后⾯导⼊的模块的功能。

all

如果⼀个模块⽂件中有 all 变量,当使⽤ from xxx import * 导⼊时,只能导⼊这个列表中的元素。

  1. __all__ = ['testA']
  2. def testA():
  3. print('testA')
  4. def testB():
  5. print('testB')
  6. ## 导⼊模块的⽂件代码
  7. from my_module1 import *
  8. testA()
  9. testB()

包将有联系的模块组织在⼀起,即放到同⼀个⽂件夹下,并且在这个⽂件夹创建⼀个名字为 init.py ⽂件,那么这个⽂件夹就称之为包。

新建包

[New] — [Python Package] — 输⼊包名 — [OK] — 新建功能模块(有联系的模块)。

注意:新建包后,包内部会⾃动创建 init.py ⽂件,这个⽂件控制着包的导⼊⾏为。

  1. 新建包 mypackage
  2. 新建包内模块: my_module1 和 my_module2
  3. 模块内代码如下
  1. # my_module1
  2. print(1)
  3. def info_print1():
  4. print('my_module1')
  5. # my_module2
  6. print(2)
  7. def info_print2():
  8. print('my_module2')

导⼊包

  1. ## import 包名.模块名
  2. ## 包名.模块名.⽬标
  3. import my_package.my_module1
  4. my_package.my_module1.info_print1()
  5. ## 必须在 __init__.py ⽂件中添加 __all__ = [] ,控制允许导⼊的模块列表。
  6. from my_package import *
  7. my_module1.info_print1()