如何创建类似slice的、实例属性全只读的一等对象类?
如何创建类似内置
slice的类?拆解内置slice的特殊行为 嘿,这个问题挖到了Python内置类型的底层细节,相当有意思!我来一步步帮你理清楚:
首先搞懂:内置slice为什么没有__dict__?
内置的slice是用C语言实现的扩展类型,不是纯Python类——这是它所有特殊行为的核心原因。
虽然它的元类确实是type,但C扩展类型可以绕过Python层面的很多默认规则:
- 它的实例属性不是存储在
__dict__里,而是直接存在C结构体的字段中,根本不需要__dict__来动态存储属性。 - 属性的只读特性也是在C层面实现的:当你尝试修改
slice实例的start/stop/step时,C代码会直接抛出AttributeError,完全不需要Python层面重写__setattr__。
而我们用纯Python写的类,默认会给每个实例分配__dict__,用来支持动态添加属性——除非你用__slots__显式禁用它。
用纯Python复刻类似slice的类
要实现一个“没有__dict__、属性只读”的类,我们可以结合__slots__和自定义__setattr__来模拟:
示例代码
class MySlice: # 用__slots__定义允许的属性,同时禁用__dict__ __slots__ = ('start', 'stop', 'step') def __init__(self, start=None, stop=None, step=None): # 初始化时直接调用object的__setattr__,绕过自定义的限制 object.__setattr__(self, 'start', start) object.__setattr__(self, 'stop', stop) object.__setattr__(self, 'step', step) def __setattr__(self, name, value): # 阻止任何后续的属性修改 raise AttributeError(f"Cannot assign to attribute '{name}' of MySlice instance") def __repr__(self): return f"MySlice(start={self.start}, stop={self.stop}, step={self.step})"
测试验证
# 创建实例 s = MySlice(1, 10, 2) print(s) # 输出: MySlice(start=1, stop=10, step=2) # 验证没有__dict__ print(hasattr(s, '__dict__')) # 输出: False # 尝试修改属性会报错 try: s.start = 5 except AttributeError as e: print(e) # 输出: Cannot assign to attribute 'start' of MySlice instance
补充说明
如果你不需要完全禁用所有属性修改,也可以用
property给每个属性设置只读的setter:class MySlice: __slots__ = ('_start', '_stop', '_step') def __init__(self, start=None, stop=None, step=None): self._start = start self._stop = stop self._step = step @property def start(self): return self._start @property def stop(self): return self._stop @property def step(self): return self._step这种方式更灵活,但本质还是依赖
__slots__移除__dict__。内置
slice没有用__slots__,因为它根本不需要Python层面的属性存储机制——C实现直接跳过了这些环节。
内容的提问来源于stack exchange,提问作者Charif DZ
相关产品推荐
相关产品推荐

