[英]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.