【发布时间】:2021-09-05 07:53:51
【问题描述】:
所以我一直在阅读描述符以尝试更好地了解它们是如何工作的,虽然我知道你不能真正禁止 Python 中的东西,但灯泡亮了,我想到了这个想法(我记得读过关于实例绑定描述符here 并借用实现):
class Immutable:
__slots__ = "name"
def __init__(self, name):
def name_setter(obj, val):
print("Cannot change name!")
self.name = property(lambda obj: name, name_setter)
def __setattr__(self, attr, value):
try:
# Try invoking the descriptor protocol __set__ "manually"
got_attr = super().__getattribute__(attr)
got_attr.__set__(self, value)
except AttributeError:
# Attribute is not a descriptor, just set it:
super().__setattr__(attr, value)
def __getattribute__(self, attr):
# If the attribute does not exist, super().__getattribute__()
# will raise an AttributeError
got_attr = super().__getattribute__(attr)
try:
# Try "manually" invoking the descriptor protocol __get__()
return got_attr.__get__(self, type(self))
except AttributeError:
# Attribute is not a descriptor, just return it:
return got_attr
mark = Immutable("Mark White")
print(mark.name)
mark.name = "test1"
print(mark.name)
setattr(mark, "name", "test2")
print(mark.name)
mark.__setattr__("name", "test3")
print(mark.name)
jon = Immutable("Jon Snow")
print(jon.name)
print(mark.name)
输出:
Mark White
Cannot change name!
Mark White
Cannot change name!
Mark White
Cannot change name!
Mark White
Jon Snow
Mark White
这个想法是,这限制了 name 属性被更改,因为它被创建为一个属性,其 setter 是在 __init__ 中定义的函数。此外,自定义 __setattr__ 和 __getattribute__ 函数允许描述符被实例绑定。所以值是在创建对象时设置的,就是这样。由于定义了 __slots__,即使是 __dict__ 也无法更改。
所以我的问题是:
我没有看到非常明显的东西还是这个属性真的不可改变?
【问题讨论】:
标签: python