概念:继承就是一个类可以继承另一个类的属性和方法。『父类』又称 『基类 或 超类』, 『子类』又称 『派生类』。
作用:通过继承可以实现代码的复用和扩展,避免重复编写相同的代码,让代码结构更简洁、更高效。
语法:def 子类名(父类名),例如:def Student(Person)就表示定义了一个Student类继承自Person类。
在子类中,有两种方式去调用父类的初始化方法,来实现对继承属性的初始化操作:
❏ 方式1(推荐):super().__init__(param1, param2)。
❏ 方式2:父类名.__init__(self, param1, param2)。
子类独有的属性,需要自己手动完成初始化。
示例代码:
# 定义一个Person类(父类)
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def speak(self, msg):
print(f'我叫{self.name},年龄{self.age},性别是{self.gender},我想说:{msg}')
# 定义一个Student类(子类),继承自Person类
class Student(Person):
def __init__(self, name, age, gender, stu_id, grade):
super().__init__(name, age, gender)
self.stu_id = stu_id
self.grade = grade
def study(self):
print(f'我叫{self.name},我在努力学习Python,争取做到{self.grade}年纪的第一名')
# 查看子类的属性和方法
print(Student.__dict__)
# 创建子类的实例对象
s1 = Student('李俊', 16, '男', '2026001', '初二')
print(s1.__dict__) # {'name': '李俊', 'age': 16, 'gender': '男', 'stu_id': '2026001', 'grade': '初二'}
print(type(s1)) # <class '__main__.Student'>
# 子类实例对象调用父类的方法
s1.speak('你好')
# 子类实例对象调用自己的方法
s1.study()
如果子类中定义了与父类同名的方法,则子类方法会“覆盖”父类中同名的方法,又称:重写。
# 定义一个Person类(父类)
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def speak(self, msg):
print(f'我叫{self.name},年龄{self.age},性别是{self.gender},我想说:{msg}')
# 定义一个Student类(子类),继承自Person类
class Student(Person):
def __init__(self, name, age, gender, stu_id, grade):
super().__init__(name, age, gender)
self.stu_id = stu_id
self.grade = grade
def study(self):
print(f'我叫{self.name},我在努力学习Python,争取做到{self.grade}年纪的第一名')
# 方法重写
def speak(self, msg):
super().speak(msg)
print(f'我是学生,我的学号是{self.stu_id},我正在读{self.grade}, 我想说:{msg}')
# 创建子类的实例对象
s1 = Student('李俊', 16, '男', '2026001', '初二')
# 子类实例对象调用自己的重写了父类方法
s1.speak('你好')
两个常用函数:
❏ isinstance(obj, Class)判断对象是否为指定类或其子类的实例。
❏ issubclass(Sub, Super)判断一个类是否是另一个类的子类。
示例代码:
# 定义一个Person类(父类)
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def speak(self, msg):
print(f'我叫{self.name},年龄{self.age},性别是{self.gender},我想说:{msg}')
# 定义一个Student类(子类),继承自Person类
class Student(Person):
def __init__(self, name, age, gender, stu_id, grade):
super().__init__(name, age, gender)
self.stu_id = stu_id
self.grade = grade
def study(self):
print(f'我叫{self.name},我在努力学习Python,争取做到{self.grade}年纪的第一名')
# 方法重写
def speak(self, msg):
# super().speak(msg)
print(f'我是学生,我的学号是{self.stu_id},我正在读{self.grade}, 我想说:{msg}')
p1 = Person('张三', 18, '男')
s1 = Student('李俊', 16, '男', '2026001', '初二')
print(isinstance(s1, Student)) # True
print(isinstance(p1, Person)) # True
print(isinstance(s1, Person)) # True
print(isinstance(p1, Student)) # False
print(issubclass(Student, Person)) # True
print(issubclass(Person, Student)) # False
print(issubclass(Person, Person)) # True
print(issubclass(Student, Student)) # True
概念:多重继承指一个类同时继承多个父类,从而拥有多个父类的属性和方法。
语法:
class 子类名(父类A, 父类B, ...):
# 子类可以继承多个父类的属性和方法
...
下面的示例代码中,Student类同时继承Person类和Worker类。
# 定义一个Person类
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def speak(self):
print(f'我叫{self.name},年龄{self.age},性别{self.gender}')
# 定义一个Worker类
class Worder:
def __init__(self, company):
self.company = company
def do_work(self):
print(f'我在{self.company}做兼职')
# 定义一个Student类,继承自:Person类,Worker 类
class Student(Person, Worder):
def __init__(self, name, age, gender, stu_id, grade, company):
Person.__init__(self, name, age, gender)
Worder.__init__(self, company)
self.stu_id = stu_id
self.grade = grade
def study(self):
print(f'我在很努力的学习,争取做{self.grade}年纪的第一名')
# 创建Student实例对象
s1 = Student('张三', 18, '男', '2026001', '大一', '肯德基')
print(s1.__dict__)
s1.speak()
s1.do_work()
s1.study()
# 查看属性和方法的查找顺序
print(Student.__mro__) # (<class '__main__.Student'>, <class '__main__.Person'>, <class '__main__.Worder'>, <class 'object'>)
扩展:
类的
__mro__属性用于记录属性和方法的查找顺序。通过实例去查找属性和方法时,会先在实例自身上查找,如果没有,就按照
__mro__中记录的顺序去查找。
在Python中,我们可以给属性赋予三种权限,分别是:

示例代码:
class Person:
def __init__(self, name, age, idcard):
self.name = name
self._age = age
self.__idcard = idcard
def speak(self):
# 类的内部,可以访问任何权限的属性(公有属性、受保护属性、私有属性)。
print(f'我叫{self.name},年龄{self._age},身份证:{self.__idcard}')
class Student(Person):
def hello(self):
# 子类的内部可以访问:公有属性、受保护属性
print(f'我是学生,我叫{self.name},年龄{self._age}')
p1 = Person('张三', 18, '110101199001011234')
# 类的外部,仅能访问公有属性
print(p1.name)
print(p1._age) # 在类的外部强制访问受保护的属性,也可以访问,但是不建议这样做
# print(p1.__idcard) # 运行时直接报错:AttributeError: 'Person' object has no attribute '__idcard'
# 扩展:Python 保护私有属性的方式是重命名,例如:__idcard属性,会被重命名为:_Person__idcard
print(p1.__dict__)
print(p1._Person__idcard) # 但是不建议这样访问
在面向对象编程中,我们会把一些内部数据保护起来,但同时还想提供一个“安全的通道”让外部访问。
这个时候我们就会用到:
在 Python 中,通过@property和@xxx.setter语法,把普通方法变成属性一样使用的方法。
示例代码:
class Person:
def __init__(self, name, age, idcard):
self.name = name
self._age = age
self.__idcard = idcard
# 注册 age 属性的 getter 方法,当访问 Person 实例的 age 属性时,会自动调用此方法
@property
def age(self):
return self._age
# 注册 age 属性的 setter 方法,当给 Person 实例的 age 属性赋值时,会自动调用此方法
@age.setter
def age(self, value):
if (value <= 120):
self._age = value
else:
print('年龄非法,已将年龄变为最大值120')
self._age = 120
# 注册 idcard 属性的 getter 方法,当访问 Person 实例的 idcard 属性时,会自动调用此方法
@property
def idcard(self):
return self.__idcard[:6] + '********' + self.__idcard[-4:]
# 注册 idcard 属性的 setter 方法,当给 Person 实例的 idcard 属性赋值时,内部会禁止修改身份证号并给出提示
@idcard.setter
def idcard(self, value):
print('抱歉,身份证号不允许随意修改,如有特殊需求,请联系管理员')
p1 = Person('张三', 18, '110101199001011234')
print(p1.age)
print(p1.idcard)
p1.age = 21
print(p1.age)
p1.idcard = 'asdd'
print(p1.idcard)
print(p1.__dict__)
print(Person.__dict__)
概念:以__xxx__命名的特殊方法(双下划线开头和结尾)。
特点:不需要手动调用,在特定场景由 Python 自动调用。
几个常用的魔术方法:

示例代码:
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def __str__(self):
return f'姓名:{self.name}, 年龄:{self.age}, 性别:{self.gender}'
def __len__(self):
return len(self.__dict__)
def __lt__(self, other):
return self.age < other.age
def __gt__(self, other):
return self.age > other.age
def __eq__(self, other):
return self.__dict__ == other.__dict__
def __getattr__(self, name):
print(f'您访问的{name}属性,不存在!')
p1 = Person('张三', 18, '男')
p2 = Person('李四', 21, '女')
print(p1)
print(str(p1))
print(len(p1))
print(p1 < p2)
print(p1 > p2)
print(p1 == p2)
print(p1.address)
object 是所有类的最终祖先,所有的类,无论写与不写,都继承自object。
object 提供了所有对象都会有的一组最基本的方法,例如:

上述这些方法,如果我们不去重写,Python 会自动继承并使用默认版本。
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
# 验证所有的类都继承了 object 类
print(issubclass(Person, object)) # True
print(issubclass(int, object)) # True
print(issubclass(str, object)) # True
print(issubclass(bool, object)) # True
print(issubclass(list, object)) # True
print(issubclass(tuple, object)) # True
print(issubclass(set, object)) # True
print(issubclass(dict, object)) # True
print()
# 验证python中所有对象都是 object 类的实例
p1 = Person('张三', 18, '男')
print(isinstance(p1, object)) # True
print(isinstance(100, object)) # True
print(isinstance('hello', object)) # True
print(isinstance(False, object)) # True
print(isinstance([1, 2, 3], object)) # True
print(isinstance((1, 2, 3), object)) # True
print(isinstance({1, 2, 3}, object)) # True
print(isinstance({'James': 41, 'Kobe': 48}, object)) # True
# 查看 object 所有的属性和方法
for key in object.__dict__:
print(key, object.__dict__[key])
print(p1.__dict__) # 打印对象自己身上的东西
print(dir(p1)) # 打印对象能访问到的东西
# 下面三种写法等价
print(p1.__str__())
print(p1)
print(str(p1))
多态(Polymorphism)是面向对象编程的三大特性之一,指同一个操作或方法作用于不同类型的对象时,可以表现出不同的行为。简单来说,就是“一个接口,多种实现”。在 Python 中,多态主要通过以下两种形式:标准多态和鸭子多态,下面分别详细介绍。
标准多态,又叫“传统多态”,基于继承与方法重写:子类重写父类的方法,当使用父类类型的引用调用该方法时,实际执行的是子类的方法。
class Animal:
def speak(self):
print('动物正在发出声音')
class Dog(Animal):
def speak(self):
print('汪汪汪!')
class Cat(Animal):
def speak(self):
print('喵喵喵!')
# 注意:Pig类没有继承Animal类
class Pig:
def speak(self):
print('哼哼哼!')
# make_sound 函数要求:传入的对象必须是 Animal 类型(或其子类)
def make_sound(animal:Animal):
animal.speak()
a1 = Animal()
d1 = Dog()
c1 = Cat()
# 下面就是多态的体现
make_sound(a1) # 动物正在发出声音
make_sound(d1) # 汪汪汪!
make_sound(c1) # 喵喵喵!
# 按标准多态规则:Pig 没有继承 Animal,类型不匹配(会出现类型警告)
p1 = Pig()
make_sound(p1) # 在其它语言中会报错,虽然 Python 中能运行,但这不属于标准多态
鸭子多态(Duck Typing):指一种编程风格,它并不依靠查找对象类型来确定其是否具有正确的接口,而是直接调用或使用其方法或属性(“看起来像鸭子,叫起来也像鸭子,那么肯定就是鸭子。”)
官方文档地址:https://docs.python.org/zh-cn/3.13/glossary.html#term-duck-typing
class Dog:
def speak(self):
print('汪汪汪!')
class Cat:
def speak(self):
print('喵喵喵!')
class Pig:
def speak(self):
print('哼哼哼!')
# make_sound 函数不在限制入参类型
def make_sound(animal):
animal.speak()
d1 = Dog()
c1 = Cat()
p1 = Pig()
# 下面就是多态的体现
make_sound(d1) # 汪汪汪!
make_sound(c1) # 喵喵喵!
make_sound(p1) # 哼哼哼!
概念:抽象类(Abstract Class)是指不能被直接实例化、主要用于定义接口的类,它通常包含一个或多个抽象方法(只有声明而没有具体实现的方法)。子类必须实现这些抽象方法才能被实例化。
定义:Python 通过内置的 abc 模块(Abstract Base Classes)来支持抽象类和抽象方法的定义。具体步骤如下:
1. 导入 ABC 和 abstractmethod
从 abc 模块导入 ABC 类(作为抽象类的基类)和 abstractmethod 装饰器。
2. 定义抽象类
创建一个继承自 ABC 的类,并用 @abstractmethod 装饰需要子类强制实现的方法。
3. 实例化限制
如果子类没有实现所有抽象方法,则子类本身也是抽象类,无法被实例化。
4. 普通方法
抽象类不仅可以包含抽象方法,也可以包含普通方法(即非抽象方法,带有具体实现)。这些具体方法会被子类继承,并且可以直接使用,无需子类重写。
实例代码:
from abc import ABC, abstractmethod
class MustRun(ABC):
@abstractmethod
def run(self):
pass
def test(self):
print("test method called")
class Person(MustRun):
def __init__(self, name, age):
self.name = name
self.age = age
def run(self):
print(f"run method called {self.name} with age {self.age}")
p1 = Person("P1", 20)
p1.run()
p1.test()
# m1 = MustRun() # 直接实例化抽象类运行时会报错
内存分为两个部分:栈内存、堆内存;变量在栈内存中,对象在堆内中。
Python 中变量里保存的不是数据,而是指向堆内存中对象的引用(内存地址)。

不可变对象:重新赋值会创建对象。
int 类的实例对象,时不可变对象,所以修改变量 a 时,会创建新对象,不会影响其他引用 b。
Python 中常见不可变对象有:int、float、bool、str、tuple、frozenset、None。
Python 中常见的可变对象有:list、dict、set、自定义类的实例对象。

可变对象:修改内容不改变地址。

自定义类对象的内存表示。

🔥BuildAdmin是一个永久免费开源,无需授权即可商业使用,且使用了流行技术栈快速创建商业级后台管理系统。