[英]Unchangeable Python Class Instance Attribute
所以我一直在阅读描述符以试图更好地了解它们的工作原理,虽然我知道你不能真正禁止 Python 中的东西,但灯泡亮了,我想到了这个想法(我记得阅读过实例绑定描述符在这里并借用了实现):
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__也不能改变。
所以我的问题是:
我是不是没有看到非常明显的东西,或者这个属性真的不能改变吗?
不,这个属性肯定是可变的:
object.__setattr__(mark, 'name', 'Foo')
将成功设置名称。
不确定“实例绑定”描述符的意义是什么。 这永远不会通过任何理智的代码审查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.