MST

星途 面试题库

面试题:Python模块命名空间与作用域之元类中的命名空间

在Python中,我们知道元类用于创建类。假设定义了一个元类 `Meta` 和一个使用该元类的类 `MyClass` 如下: ```python class Meta(type): def __new__(cls, name, bases, namespace): new_namespace = {} for key, value in namespace.items(): if not key.startswith('__'): new_key = 'custom_' + key new_namespace[new_key] = value return super().__new__(cls, name, bases, new_namespace) class MyClass(metaclass = Meta): def original_method(self): return 'Original method' ``` 1. 请解释 `Meta` 元类的 `__new__` 方法中对 `namespace` 进行操作的原理。 2. 当实例化 `MyClass` 并调用 `original_method` 时,Python如何在修改后的命名空间和作用域中查找该方法? 3. 如果在 `MyClass` 中定义了一个类变量 `my_var`,它在命名空间和作用域中的行为与实例方法有何不同?
13.9万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
  1. Meta 元类的 __new__ 方法中对 namespace 进行操作的原理
    • namespace 是一个字典,它包含了在类定义体中定义的所有属性和方法。
    • 遍历 namespace 中的每一个键值对。
    • 对于不是以双下划线 __ 开头的键(即用户自定义的属性和方法),在新的键名前加上 custom_,并将对应的值放入新的命名空间 new_namespace 中。
    • 最后,通过 super().__new__(cls, name, bases, new_namespace) 创建一个新的类对象,使用修改后的命名空间。这样就实现了对类定义中的属性和方法进行重命名(添加前缀 custom_)。
  2. 当实例化 MyClass 并调用 original_method 时,Python如何在修改后的命名空间和作用域中查找该方法
    • 当调用 MyClass 的实例的 original_method 时,Python 首先在实例的命名空间中查找该方法,因为实例本身没有 original_method 方法,所以查找失败。
    • 接着,Python 会在实例的类 MyClass 的命名空间中查找。但是,在类定义时,Meta 元类已经将 original_method 重命名为 custom_original_method。所以直接查找 original_method 会失败。
    • 如果要成功调用该方法,需要使用 custom_original_method 来调用,例如 my_obj = MyClass(); my_obj.custom_original_method()
  3. 如果在 MyClass 中定义了一个类变量 my_var,它在命名空间和作用域中的行为与实例方法有何不同
    • 命名空间
      • 实例方法:实例方法存储在类的命名空间中,在元类 Meta__new__ 方法中,实例方法的名称被修改(添加 custom_ 前缀)。实例通过类的命名空间来访问实例方法。
      • 类变量:类变量也存储在类的命名空间中。在元类 Meta__new__ 方法处理时,类变量同样会被重命名(添加 custom_ 前缀)。例如,如果定义 my_var,它会被重命名为 custom_my_var
    • 作用域
      • 实例方法:实例方法的作用域主要与实例相关,通过实例来调用,每个实例调用方法时,方法中的 self 指代具体的实例对象。
      • 类变量:类变量的作用域是整个类及其所有实例共享的。所有实例都可以访问和修改类变量(如果允许修改)。当通过实例访问类变量时,如果实例没有同名的实例变量,就会访问到类的命名空间中的类变量。在重命名后,无论是通过类还是实例访问类变量,都需要使用重命名后的名称(如 custom_my_var)。