当前位置: 首页 > news >正文

Python面试题及详细答案150道(41-55) -- 面向对象编程篇

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

文章目录

  • 一、本文面试题目录
      • 41. 解释面向对象的三大特性:封装、继承、多态。
      • 42. Python中如何定义类和创建对象?
      • 43. 什么是`self`?它在类方法中的作用是什么?
      • 44. 类的实例方法、类方法(`@classmethod`)、静态方法(`@staticmethod`)的区别。
      • 45. 如何实现类的继承?子类如何调用父类的方法?
      • 46. 什么是方法重写(Override)?
      • 47. 什么是抽象类(Abstract Class)?如何在Python中定义抽象类?
      • 48. 什么是魔术方法(Magic Method)?举例说明几个常用的魔术方法(如`__init__`、`__str__`、`__repr__`)。
      • 49. `__new__`和`__init__`的区别是什么?
      • 50. 什么是单例模式?如何在Python中实现单例模式?
      • 52. 类的私有属性和私有方法如何定义?是否真的“私有”?
      • 53. 什么是属性装饰器(`@property`)?如何使用?
      • 54. 解释多继承中的MRO(方法解析顺序)。
      • 55. 如何判断一个对象是否是某个类的实例?(`isinstance()`和`type()`的区别)
  • 二、150道Python面试题目录列表

一、本文面试题目录

41. 解释面向对象的三大特性:封装、继承、多态。

面向对象编程(OOP)的三大核心特性是封装、继承和多态,它们共同构成了面向对象设计的基础:

  1. 封装(Encapsulation)
    将数据(属性)和操作数据的方法(函数)捆绑在一起,隐藏内部实现细节,只通过公开接口与对象交互。

    • 作用:提高安全性(防止数据被意外修改)、简化使用(只需关注接口)。
      示例:
    class BankAccount:def __init__(self, balance):self.__balance = balance  # 私有属性(封装)def deposit(self, amount):if amount > 0:self.__balance += amountdef get_balance(self):  # 公开接口return self.__balanceaccount = BankAccount(100)
    account.deposit(50)
    print(account.get_balance())  # 150(通过接口访问)
    # print(account.__balance)  # 错误:无法直接访问私有属性
    
  2. 继承(Inheritance)
    子类(派生类)可以继承父类(基类)的属性和方法,并可添加新功能或重写父类方法。

    • 作用:代码复用、建立类之间的层次关系。
      示例:
    class Animal:def speak(self):passclass Dog(Animal):  # 继承Animaldef speak(self):  # 重写父类方法return "Woof"class Cat(Animal):  # 继承Animaldef speak(self):  # 重写父类方法return "Meow"
    
  3. 多态(Polymorphism)
    不同类的对象对同一方法调用可产生不同结果,即“同一接口,多种实现”。

    • 作用:提高代码灵活性和可扩展性。
      示例:
    def make_speak(animal):print(animal.speak())  # 同一接口,不同实现dog = Dog()
    cat = Cat()
    make_speak(dog)  # 输出:Woof
    make_speak(cat)  # 输出:Meow
    

42. Python中如何定义类和创建对象?

在Python中,使用class关键字定义类,通过类名加括号()创建对象(实例化)。

定义类的语法

class 类名:# 类属性(所有实例共享)类变量 =# 构造方法(初始化实例)def __init__(self, 参数):self.实例变量 = 参数  # 实例属性# 实例方法def 方法名(self, 参数):方法体

创建对象(实例化)

对象名 = 类名(参数)  # 调用__init__方法初始化

完整示例

# 定义类
class Person:# 类属性(所有Person共享)species = "Homo sapiens"# 构造方法:初始化实例属性def __init__(self, name, age):self.name = name  # 实例属性self.age = age    # 实例属性# 实例方法def greet(self):return f"Hello, my name is {self.name}"# 创建对象(实例化)
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)# 访问实例属性和方法
print(person1.name)    # Alice
print(person1.greet()) # Hello, my name is Alice# 访问类属性
print(person1.species) # Homo sapiens
print(Person.species)  # Homo sapiens(通过类名访问)

说明

  • __init__是构造方法,在创建对象时自动调用,用于初始化实例属性。
  • 实例属性通过self.属性名定义,每个对象有独立的实例属性。
  • 类属性属于类本身,所有实例共享同一类属性。

43. 什么是self?它在类方法中的作用是什么?

self是类方法中第一个参数的约定名称,代表调用该方法的实例对象本身。

作用

  1. 区分实例属性和局部变量:通过self.属性名访问或定义实例属性。
  2. 在方法中调用同一类的其他方法或属性。
  3. 标识当前对象,确保方法操作的是调用者自身的数据。

示例

class Car:def __init__(self, color):self.color = color  # self区分实例属性color和参数colordef describe(self):# self访问实例属性return f"This car is {self.color}"def repaint(self, new_color):self.color = new_color# self调用同一类的其他方法return self.describe()my_car = Car("red")
print(my_car.describe())  # This car is red
print(my_car.repaint("blue"))  # This car is blue

注意

  • self不是Python的关键字,只是约定名称,理论上可替换为其他名称,但不推荐。
  • 调用实例方法时,Python会自动将当前对象作为第一个参数传递,无需手动传入。
    my_car.describe()  # 等价于 Car.describe(my_car)
    
  • 类方法(@classmethod)中使用cls代替self,代表类本身。

44. 类的实例方法、类方法(@classmethod)、静态方法(@staticmethod)的区别。

Python类中有三种方法类型,用途和特性不同:

类型定义方式第一个参数访问权限用途
实例方法直接定义self(实例)可访问实例属性和类属性操作实例数据
类方法@classmethod装饰cls(类)可访问类属性,不可访问实例属性操作类数据、创建备选构造方法
静态方法@staticmethod装饰无特殊参数不可直接访问实例/类属性提供与类相关的工具函数,逻辑独立于类数据

示例

class MyClass:class_attr = "类属性"  # 类属性def __init__(self, instance_attr):self.instance_attr = instance_attr  # 实例属性# 实例方法def instance_method(self):print(f"实例方法:访问实例属性 {self.instance_attr},类属性 {self.class_attr}")# 类方法@classmethoddef class_method(cls):print(f"类方法:访问类属性 {cls.class_attr}")# print(cls.instance_attr)  # 错误:类方法不能访问实例属性# 静态方法@staticmethoddef static_method(x, y):print(f"静态方法:计算结果 {x + y}")# print(self.instance_attr)  # 错误:静态方法无self# print(cls.class_attr)      # 错误:静态方法无cls# 使用示例
obj = MyClass("实例属性")# 调用实例方法
obj.instance_method()  # 实例方法:访问实例属性 实例属性,类属性 类属性# 调用类方法(可通过实例或类调用)
obj.class_method()     # 类方法:访问类属性 类属性
MyClass.class_method() # 类方法:访问类属性 类属性# 调用静态方法(可通过实例或类调用)
obj.static_method(2, 3)  # 静态方法:计算结果 5
MyClass.static_method(4, 5)  # 静态方法:计算结果 9

总结

  • 实例方法:依赖实例状态,用于对象的具体操作。
  • 类方法:依赖类状态,常用于创建工厂方法或操作类级别的数据。
  • 静态方法:独立于类和实例,更像类内部的普通函数,用于逻辑上与类相关的工具功能。

45. 如何实现类的继承?子类如何调用父类的方法?

类的继承是指子类(派生类)继承父类(基类)的属性和方法,通过在类定义时在括号中指定父类实现。

语法

class 父类:# 父类属性和方法class 子类(父类):  # 继承父类# 子类可添加新属性/方法,或重写父类方法

子类调用父类方法的方式

  1. 使用super().方法名()(推荐,尤其多继承时)。
  2. 使用父类名.方法名(self, 参数)

示例

# 父类
class Animal:def __init__(self, name):self.name = namedef speak(self):return "Animal sound"# 子类继承父类
class Dog(Animal):def __init__(self, name, breed):# 调用父类的__init__方法super().__init__(name)  # 方式1:super()# Animal.__init__(self, name)  # 方式2:父类名self.breed = breed  # 子类新增属性# 重写父类方法def speak(self):return "Woof"# 子类新增方法def fetch(self):return f"{self.name} is fetching"# 使用子类
dog = Dog("Buddy", "Golden Retriever")
print(dog.name)      # Buddy(继承自父类的属性)
print(dog.breed)     # Golden Retriever(子类新增属性)
print(dog.speak())   # Woof(重写的方法)
print(dog.fetch())   # Buddy is fetching(新增方法)

多继承示例

class Flyable:def fly(self):return "Flying"class Bird(Animal, Flyable):  # 继承多个父类def speak(self):return "Chirp"bird = Bird("Tweety")
print(bird.speak())  # Chirp(重写Animal的方法)
print(bird.fly())    # Flying(继承Flyable的方法)

说明

  • 子类可继承父类的所有非私有属性和方法。
  • super()在单继承中指向父类,在多继承中遵循MRO(方法解析顺序)。
  • 多继承时,父类之间用逗号分隔。

46. 什么是方法重写(Override)?

方法重写(Method Override) 是指子类定义与父类同名的方法,从而覆盖父类方法的实现。子类通过重写可以修改或扩展父类方法的功能,是多态的基础。

作用

  • 使子类能够根据自身需求定制父类的方法。
  • 保持接口一致(方法名相同)但实现不同,体现多态。

示例

class Shape:# 父类方法def area(self):raise NotImplementedError("子类必须重写area方法")# 子类重写父类方法
class Circle(Shape):def __init__(self, radius):self.radius = radius# 重写area方法def area(self):return 3.14 * self.radius **2# 子类重写父类方法
class Rectangle(Shape):def __init__(self, width, height):self.width = widthself.height = height# 重写area方法def area(self):return self.width * self.height# 多态体现:同一方法名,不同实现
shapes = [Circle(5), Rectangle(4, 6)]
for shape in shapes:print(f"面积:{shape.area()}")  # 分别调用子类的area方法# 输出:
# 面积:78.5
# 面积:24

重写时扩展父类功能
子类可在重写方法中调用父类方法,再添加新逻辑:

class Parent:def greet(self):return "Hello from Parent"class Child(Parent):def greet(self):# 调用父类方法parent_greeting = super().greet()# 扩展功能return f"{parent_greeting}\nHello from Child"child = Child()
print(child.greet())
# 输出:
# Hello from Parent
# Hello from Child

注意

  • 重写方法的参数列表应与父类保持一致(或兼容),否则可能导致调用错误。
  • 如果父类方法是抽象方法(如示例中的Shape.area),子类必须重写该方法,否则实例化会报错。

47. 什么是抽象类(Abstract Class)?如何在Python中定义抽象类?

抽象类(Abstract Class) 是一种不能被实例化的类,用于定义子类必须实现的接口(方法)。抽象类可以包含抽象方法(只有声明没有实现)和具体方法(有实现)。

作用

  • 强制子类遵循统一的接口规范(必须实现抽象方法)。
  • 作为多个子类的基类,提取公共逻辑。

在Python中定义抽象类
需通过abc模块(Abstract Base Classes)的ABCMeta元类和@abstractmethod装饰器实现。

示例

from abc import ABCMeta, abstractmethod# 定义抽象类(继承ABCMeta)
class Vehicle(metaclass=ABCMeta):# 抽象方法(必须被子类实现)@abstractmethoddef start(self):pass# 抽象方法@abstractmethoddef stop(self):pass# 具体方法(可被继承或重写)def honk(self):return "Honking!"# 子类必须实现所有抽象方法
class Car(Vehicle):def start(self):return "Car started"def stop(self):return "Car stopped"class Bike(Vehicle):def start(self):return "Bike started"def stop(self):return "Bike stopped"# 使用子类
car = Car()
print(car.start())  # Car started
print(car.honk())   # Honking!bike = Bike()
print(bike.start())  # Bike started# 错误:抽象类不能实例化
# vehicle = Vehicle()  # TypeError: Can't instantiate abstract class Vehicle with abstract methods start, stop# 错误:子类未实现所有抽象方法
class Truck(Vehicle):def start(self):return "Truck started"# 未实现stop()方法# truck = Truck()  # TypeError: Can't instantiate abstract class Truck with abstract method stop

说明

  • 抽象类不能直接实例化,必须通过子类实例化。
  • 子类必须实现抽象类中的所有抽象方法,否则子类仍为抽象类,无法实例化。
  • 抽象类可以包含具体方法,提供子类可复用的功能。

48. 什么是魔术方法(Magic Method)?举例说明几个常用的魔术方法(如__init____str____repr__)。

魔术方法(Magic Method) 是Python中以双下划线__开头和结尾的特殊方法,用于定义类的行为(如初始化、字符串表示、运算符重载等)。它们会在特定场景下自动调用,无需手动调用。

常用魔术方法示例

1.__init__(self, ...):构造方法
对象实例化时自动调用,用于初始化实例属性。

class Person:def __init__(self, name, age):self.name = nameself.age = agep = Person("Alice", 30)  # 自动调用__init__

2.__str__(self):字符串表示
当使用str(obj)print(obj)时调用,返回可读性高的字符串。

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return f"Person: {self.name}, {self.age}岁"p = Person("Alice", 30)
print(p)  # 自动调用__str__ → Person: Alice, 30岁

3.__repr__(self):官方字符串表示
当使用repr(obj)时调用,返回用于调试的官方字符串(通常可用于重建对象)。

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __repr__(self):return f"Person('{self.name}', {self.age})"p = Person("Alice", 30)
print(repr(p))  # 输出:Person('Alice', 30)

注:如果未定义__str__print(obj)会使用__repr__的结果。

4.__len__(self):长度计算
当使用len(obj)时调用,返回对象的“长度”。

class MyList:def __init__(self, items):self.items = itemsdef __len__(self):return len(self.items)ml = MyList([1, 2, 3])
print(len(ml))  # 自动调用__len__ → 3

5.__add__(self, other):加法运算符重载
当使用obj1 + obj2时调用,定义对象的加法行为。

class Point:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):return Point(self.x + other.x, self.y + other.y)def __str__(self):return f"({self.x}, {self.y})"p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2  # 自动调用__add__
print(p3)  # (4, 6)

其他常用魔术方法

  • __eq__(self, other):定义==运算符行为。
  • __getitem__(self, key):定义obj[key]索引访问。
  • __call__(self, ...):使对象可像函数一样被调用(obj())。

49. __new____init__的区别是什么?

__new____init__都是Python中的魔术方法,与对象创建相关,但作用和调用时机不同:

特性__new____init__
作用创建对象(实例化),返回新对象初始化对象,设置实例属性
第一个参数cls(类本身)self(已创建的实例)
返回值必须返回一个实例(通常是cls的实例)无返回值(None
调用时机在对象创建前调用在对象创建后(__new__之后)调用
使用场景控制实例创建过程(如单例模式)初始化实例属性

示例

class MyClass:def __new__(cls, *args, **kwargs):print("__new__被调用,创建对象")# 调用父类的__new__创建实例instance = super().__new__(cls)return instance  # 必须返回实例def __init__(self, value):print("__init__被调用,初始化对象")self.value = value  # 设置实例属性# 创建对象的过程
obj = MyClass(10)
# 输出:
# __new__被调用,创建对象
# __init__被调用,初始化对象print(obj.value)  # 10

__new__的特殊用途

  1. 单例模式:确保类只有一个实例

    class Singleton:_instance = Nonedef __new__(cls):if cls._instance is None:cls._instance = super().__new__(cls)return cls._instancea = Singleton()
    b = Singleton()
    print(a is b)  # True(a和b是同一实例)
    
  2. 不可变类的子类化:如自定义intstr等不可变类型

    class PositiveInt(int):def __new__(cls, value):# 确保值为正数if value <= 0:raise ValueError("必须是正数")return super().__new__(cls, value)num = PositiveInt(10)
    # num2 = PositiveInt(-5)  # 报错:ValueError
    

总结

  • __new__负责“创建”对象,是类级别的方法。
  • __init__负责“初始化”对象,是实例级别的方法。
  • 多数情况下只需重写__init____new__仅在需要控制实例创建时使用。

50. 什么是单例模式?如何在Python中实现单例模式?

单例模式(Singleton Pattern) 是一种设计模式,确保一个类只能创建一个实例,并提供全局访问点。

应用场景

  • 配置管理(全局唯一配置)
  • 日志记录器(避免多个日志实例冲突)
  • 数据库连接池(控制连接数量)

Python中实现单例模式的方法

1.** 使用__new__方法 **(最常用)

class Singleton:_instance = None  # 存储唯一实例def __new__(cls, *args, **kwargs):# 如果实例不存在,则创建if not cls._instance:cls._instance = super().__new__(cls)return cls._instance# 测试
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True(同一实例)

2.** 使用装饰器 **```python
def singleton(cls):
instances = {} # 缓存实例

   def wrapper(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper

@singleton
class MyClass:
pass

测试
m1 = MyClass()
m2 = MyClass()
print(m1 is m2) # True


3.** 使用模块 **(Python特有,最简单)  
Python模块在第一次导入时执行,后续导入直接引用已加载的模块对象,天然是单例。
```python
# singleton_module.py
class Singleton:def some_method(self):return "This is a singleton"# 创建唯一实例
instance = Singleton()# 使用方式
# from singleton_module import instance
# a = instance
# b = instance
# print(a is b)  # True

4.** 使用元类(Metaclass)**```python
class SingletonMeta(type):
_instances = {}

   def __call__(cls, *args, **kwargs):if cls not in cls._instances:cls._instances[cls] = super().__call__(*args, **kwargs)return cls._instances[cls]

应用元类
class MySingleton(metaclass=SingletonMeta):
pass

测试
s1 = MySingleton()
s2 = MySingleton()
print(s1 is s2) # True


**注意**:
- 单例模式可能导致全局状态,增加代码耦合度,应谨慎使用。
- 在多线程环境下,需添加线程锁确保单例安全性。### 51. 什么是Mixin模式?它的作用是什么?**Mixin模式**(混合模式)是一种通过多继承复用类功能的设计模式。Mixin类是包含一组可复用方法的类,本身不单独实例化,而是被其他类继承以扩展功能。**作用**:
- 实现代码复用,避免重复编写相同功能。
- 灵活组合功能,无需复杂的继承层次。
- 解决单继承的局限性,实现“多继承”的优势而避免其复杂性。**示例**:
```python
# Mixin类:提供飞行功能
class FlyableMixin:def fly(self):return f"{self.name} is flying"# Mixin类:提供游泳功能
class SwimmableMixin:def swim(self):return f"{self.name} is swimming"# 基础类
class Animal:def __init__(self, name):self.name = name# 继承基础类和Mixin类,组合功能
class Duck(Animal, FlyableMixin, SwimmableMixin):def quack(self):return "Quack!"# 使用
duck = Duck("Donald")
print(duck.quack())  # Quack!(自身方法)
print(duck.fly())    # Donald is flying(来自FlyableMixin)
print(duck.swim())   # Donald is swimming(来自SwimmableMixin)

Mixin设计原则

  1. 单一职责:每个Mixin类专注于一组相关功能。
  2. 不单独实例化:Mixin类仅用于被继承,自身不创建实例。
  3. 依赖约定:Mixin类通常假设被继承的类有特定属性或方法(如示例中假设存在name属性)。
  4. 命名规范:Mixin类名通常以Mixin结尾,明确其用途。

应用场景

  • 为类添加通用功能(如日志、缓存、序列化)。
  • 在框架中扩展组件功能(如Django的LoginRequiredMixin)。

示例:Django中的Mixin

# Django视图中使用Mixin添加登录验证
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateViewclass MyView(LoginRequiredMixin, TemplateView):template_name = "my_template.html"# 未登录用户会被重定向到登录页(功能来自LoginRequiredMixin)

52. 类的私有属性和私有方法如何定义?是否真的“私有”?

在Python中,通过在属性或方法名前加双下划线__定义私有属性和私有方法,目的是限制外部直接访问。

定义方式

class MyClass:def __init__(self):self.public_attr = "公共属性"self.__private_attr = "私有属性"  # 私有属性def public_method(self):return "公共方法"def __private_method(self):  # 私有方法return "私有方法"def access_private(self):# 类内部可访问私有属性和方法return f"{self.__private_attr}, {self.__private_method()}"

外部访问限制

obj = MyClass()# 访问公共成员
print(obj.public_attr)    # 公共属性
print(obj.public_method())  # 公共方法# 直接访问私有成员会报错
# print(obj.__private_attr)    # AttributeError
# print(obj.__private_method())  # AttributeError# 类内部可访问私有成员
print(obj.access_private())  # 私有属性, 私有方法

是否真的“私有”?
Python的私有机制是通过“名称修饰(Name Mangling)”实现的,并非真正的私有:

  • 解释器会将私有成员名__name修改为_类名__name,可通过该名称在外部访问。
# 间接访问私有成员(不推荐)
print(obj._MyClass__private_attr)    # 私有属性
print(obj._MyClass__private_method())  # 私有方法

总结

  • 私有成员的目的是“约定”而非强制限制,提醒开发者不要外部访问。
  • 名称修饰是一种保护机制,防止子类意外覆盖父类的私有成员。
  • 通常使用单下划线_表示“受保护”成员(约定不外部访问,无实际限制)。

53. 什么是属性装饰器(@property)?如何使用?

@property是Python的装饰器,用于将类的方法转换为属性,使方法可以像属性一样被访问(无需加括号调用)。

作用

  • 提供统一的属性访问接口,隐藏内部实现细节。
  • 允许在获取/设置属性时添加逻辑(如验证、计算)。
  • 使代码更简洁,符合“开放-封闭”原则。

基本用法

class Person:def __init__(self, first_name, last_name):self.first_name = first_nameself.last_name = last_name# 定义属性:full_name@propertydef full_name(self):# 计算属性值return f"{self.first_name} {self.last_name}"person = Person("John", "Doe")
print(person.full_name)  # 像属性一样访问,无需加括号 → John Doe

带设置器(Setter)和删除器(Deleter)

class Person:def __init__(self, age):self._age = age  # 用单下划线表示受保护属性#  getter:获取属性值@propertydef age(self):return self._age#  setter:设置属性值(需与属性同名)@age.setterdef age(self, value):# 添加验证逻辑if value < 0 or value > 120:raise ValueError("年龄必须在0-120之间")self._age = value#  deleter:删除属性@age.deleterdef age(self):print("删除年龄属性")del self._ageperson = Person(30)
print(person.age)  # 30(调用getter)person.age = 35    # 调用setter
print(person.age)  # 35# person.age = 150  # 报错:ValueErrordel person.age     # 调用deleter

应用场景

  1. 计算属性:如示例中的full_name,值由其他属性计算而来。
  2. 属性验证:在设置属性时检查值的合法性(如年龄范围)。
  3. 兼容旧接口:当需要将方法改为属性时,不破坏现有代码。
  4. 延迟计算:属性值在第一次访问时才计算,提高性能。

@property使属性访问既简洁又灵活,是Python面向对象编程中封装的重要工具。

54. 解释多继承中的MRO(方法解析顺序)。

MRO(Method Resolution Order,方法解析顺序) 是Python在多继承中确定方法调用顺序的规则,用于解决多个父类中存在同名方法时的调用冲突。

为什么需要MRO?
在多继承中,若多个父类有同名方法,MRO决定了子类调用该方法时的搜索顺序。

Python的MRO规则
Python 3使用“C3线性化”算法,遵循以下原则:

  1. 子类优先于父类:子类的方法优先于父类。
  2. 同一层级的父类按继承顺序搜索class C(A, B)中A优先于B。
  3. 保持父类的MRO顺序:确保父类的方法搜索顺序不变。

查看MRO的方式

  • 通过类的__mro__属性。
  • 通过cls.mro()方法。

示例

class A:def method(self):print("A.method")class B(A):def method(self):print("B.method")class C(A):def method(self):print("C.method")class D(B, C):pass  # 继承B和C# 查看D的MRO
print(D.__mro__)
# 输出:(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)# 调用method(),按MRO顺序搜索
d = D()
d.method()  # 输出:B.method(D→B→C→A→object)

复杂多继承示例

class X:def method(self):print("X.method")class Y:def method(self):print("Y.method")class A(X, Y):passclass B(Y, X):passclass C(A, B):passprint(C.mro())
# 输出:[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.X'>, <class '__main__.B'>, <class '__main__.Y'>, <class 'object'>]c = C()
c.method()  # 输出:X.method(按MRO顺序找到A→X的method)

注意

  • MRO确保每个类只被访问一次。
  • 多继承可能导致MRO复杂,应尽量避免过深的多继承层次。
  • 可通过super()函数按MRO顺序调用父类方法。

55. 如何判断一个对象是否是某个类的实例?(isinstance()type()的区别)

在Python中,可通过isinstance()type()判断对象类型,但二者有重要区别:

1.isinstance(obj, cls)
判断对象obj是否是类cls或其子类的实例,返回布尔值。

2.type(obj)
返回对象obj实际类型(类对象),可用于类型比较。

示例

class Animal:passclass Dog(Animal):  # Dog是Animal的子类passdog = Dog()# 使用isinstance()
print(isinstance(dog, Dog))      # True(是Dog的实例)
print(isinstance(dog, Animal))   # True(是父类Animal的实例)
print(isinstance(dog, object))   # True(所有类都继承自object)# 使用type()
print(type(dog) is Dog)          # True(实际类型是Dog)
print(type(dog) is Animal)       # False(实际类型不是Animal)
print(type(dog))                 # <class '__main__.Dog'>(返回类型对象)

关键区别

  • isinstance()考虑继承关系(子类实例也是父类的实例)。
  • type()只检查对象的实际类型,不考虑继承关系。

使用场景

  • 类型检查:优先使用isinstance(),因为它支持多态,更符合面向对象思想。

    def feed(animal):if isinstance(animal, Animal):  # 接受所有Animal子类print("Feeding the animal")
    
  • 精确类型判断:当需要严格区分子类和父类时,使用type()

    def get_type_name(obj):return type(obj).__name__  # 返回实际类型的名称
    

注意

  • 不要过度使用类型检查,Python更倾向于“鸭子类型”(关注对象行为而非类型)。
  • isinstance()的第二个参数可以是元组,检查对象是否是其中任一类型的实例:
    print(isinstance(5, (int, float)))  # True(5是int类型)
    

二、150道Python面试题目录列表

文章序号Python面试题150道
1Python面试题及详细答案150道(01-15)
2Python面试题及详细答案150道(16-30)
3Python面试题及详细答案150道(31-40)
4Python面试题及详细答案150道(41-55)
5Python面试题及详细答案150道(56-70)
6Python面试题及详细答案150道(71-80)
7Python面试题及详细答案150道(81-90)
8Python面试题及详细答案150道(91-100)
9Python面试题及详细答案150道(101-115)
10Python面试题及详细答案150道(116-125)
11Python面试题及详细答案150道(126-135)
12Python面试题及详细答案150道(136-150)
http://www.dtcms.com/a/325884.html

相关文章:

  • 《基于Redis实现高效消息队列的完整指南》
  • 在 RHEL9 上搭建企业级 Web 服务(Tomcat)
  • Java Selenium 自动打开浏览器保存截图
  • Spring Cloud系列—Gateway统一服务入口
  • 案例分析2:上层应用不稳定提示注册失败
  • Python(9)-- 异常模块与包
  • CLIP,BLIP,SigLIP技术详解【二】
  • Flink + Hologres构建实时数仓
  • 机器学习:基于OpenCV和Python的智能图像处理 实战
  • 【05】昊一源科技——昊一源科技 嵌入式笔试, 校招,题目记录及解析
  • 提示词注入攻防全解析——从攻击原理到防御浅谈
  • gophis钓鱼
  • 深入解析 resolv.conf 文件:DNS 配置的核心
  • 区间修改 - 差分
  • 在Linux中使用docker-compose快速搭建Prometheus监控系统
  • foreach 块并行加速
  • 澳洲增高营养品排行榜
  • 小波卷积YYDS!小波变换+CNN创新结合
  • 无人机航拍数据集|第11期 无人机人员行为目标检测YOLO数据集1868张yolov11/yolov8/yolov5可训练
  • 【bug】diff-gaussian-rasterization Windows下编译 bug 解决
  • STM32 HAL库驱动0.96寸OLED屏幕
  • 【学习】DCMM认证从“跟风“到“生存法则“的进化
  • EI检索-学术会议 | 人工智能、虚拟现实、可视化
  • react中父子数据流动和事件互相调用(和vue做比较)
  • 小杰python高级(three day)——matplotlib库
  • 关于微信小程序的笔记
  • 告别“焊武帝”时代!30-65W零外围A+C快充协议正式上线
  • Cherryusb UAC例程对接STM32内置ADC和PWM播放音乐和录音(下)=>UAC+STM32 ADC+PWM实现录音和播放
  • TradingAgents-CN: 基于多智能体的中文金融交易决策框架
  • Apache Ignite超时管理核心组件解析