面试题答案
一键面试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
。通过这种下划线命名方式,我们隐藏了实际存储数据的属性名称,实现了一定程度的访问控制。同时,语义上,下划线开头的属性表示是内部使用的,不应该被外部直接访问,从而规范了数据的访问和修改方式。