MST

星途 面试题库

面试题:Python 下划线命名在元类和描述符中的语义及实践

在元类和描述符的设计与实现中,下划线命名扮演着重要角色。请举例说明如何在自定义元类中利用下划线命名规则来控制类的创建过程,以及在描述符类中如何运用下划线命名来实现数据验证和访问控制等功能,阐述其中的语义和具体实践方式。
37.7万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

1. 在自定义元类中利用下划线命名规则控制类的创建过程

在Python中,元类是用于创建类的类。__new__方法在类创建时被调用,我们可以在自定义元类中通过下划线命名规则来控制类的创建。

class MyMeta(type):
    def __new__(mcls, name, bases, attrs):
        # 过滤掉以双下划线开头的属性
        new_attrs = {k: v for k, v in attrs.items() if not k.startswith('__')}
        return super().__new__(mcls, name, bases, new_attrs)


class MyClass(metaclass=MyMeta):
    def __init__(self):
        pass
    _private_attr = 10
    public_attr = 20


在上述代码中,MyMeta是一个自定义元类。在__new__方法中,我们通过下划线命名规则过滤掉了以双下划线开头的属性(这些属性通常是Python的特殊方法或属性)。这样在创建MyClass时,就不会包含这些被过滤的属性。语义上,双下划线开头的属性往往是Python内部使用或者具有特殊意义的,我们通过这种方式可以对类创建过程中的属性进行筛选和控制。

2. 在描述符类中运用下划线命名实现数据验证和访问控制

描述符是一种特殊的类,用于实现属性的自定义访问逻辑。

class ValidatedDescriptor:
    def __init__(self, name):
        self._name = name

    def __get__(self, instance, owner):
        if instance is None:
            return self
        return instance.__dict__.get(self._name)

    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise ValueError('Value must be an integer')
        instance.__dict__[self._name] = value


class MyDataClass:
    my_value = ValidatedDescriptor('_my_value')


data = MyDataClass()
data.my_value = 10
# data.my_value = 'not an integer'  # 这行代码会抛出ValueError

在上述代码中,ValidatedDescriptor是一个描述符类。我们使用下划线命名的_name来存储属性的实际名称。在__set__方法中,我们实现了数据验证,如果设置的值不是整数类型,则抛出ValueError。通过这种下划线命名方式,我们隐藏了实际存储数据的属性名称,实现了一定程度的访问控制。同时,语义上,下划线开头的属性表示是内部使用的,不应该被外部直接访问,从而规范了数据的访问和修改方式。