你不能让 Python 类完全不可变。不过你可以模仿它:
class C:
_immutable = False
def __setattr__(self, name, value):
if self._immutable:
raise TypeError(f"Can't set attribute, {self!r} is immutable.")
super().__setattr__(name, value)
Run Code Online (Sandbox Code Playgroud)
例子:
>>> c = C()
>>> c.hello = 123
>>> c.hello
123
>>> c._immutable = True
>>> c.hello = 456
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __setattr__
TypeError: Can't set attribute, <__main__.C object at 0x000002087C679D20> is immutable.
Run Code Online (Sandbox Code Playgroud)
如果你想在初始化时设置它,你可以添加__init__如下:
class C:
_immutable = False
def __init__(self, immutable=False):
self._immutable = immutable
def __setattr__(self, name, value):
if self._immutable:
raise TypeError(f"Can't set attribute, {self!r} is immutable.")
super().__setattr__(name, value)
Run Code Online (Sandbox Code Playgroud)
请记住,您仍然可以通过__dict__直接访问和修改实例来绕过它:
>>> c = C(immutable=True)
>>> c.__dict__["hello"] = 123
>>> c.hello
123
Run Code Online (Sandbox Code Playgroud)
您可以尝试像这样阻止它:
class C:
_immutable = False
def __init__(self, immutable=False):
self._immutable = immutable
def __getattribute__(self, name):
if name == "__dict__":
raise TypeError("Can't access class dict.")
return super().__getattribute__(name)
def __setattr__(self, name, value):
if self._immutable:
raise TypeError(f"Can't set attribute, {self!r} is immutable.")
super().__setattr__(name, value)
Run Code Online (Sandbox Code Playgroud)
但即便如此,也可以绕过:
>>> c = C(immutable=True)
>>> object.__getattribute__(c, "__dict__")["hello"] = 123
>>> c.hello
123
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
100 次 |
| 最近记录: |