【发布时间】:2023-03-29 05:23:01
【问题描述】:
我正在尝试实现一种(诚然 unPythonic)封装大量实例变量的方式。
我将这些变量的名称映射到字典中的相应值,因此我没有编写大量样板文件(即self.var = val,例如 50 次),而是在调用 __setattr__() 时遍历字典,这样:
class MyClass:
__slots__ = ("var1", "var2", "var3")
def __init__(self, data):
for k, v in data.items():
self.__setattr__(k, v)
然后我将覆盖__setattr__(),以控制对这些属性的访问。
在__setattr__() 中,我将首先检查对象是否具有该属性,以便允许在__init__() 中调用 setattr:
def __setattr__(self, k, v):
if k in self.__class__.__slots__:
if hasattr(self, k):
return print("Read-only property")
super().__setattr__(k, v)
问题是,我还需要在myClass 的其他地方写入其中的一些属性,即使它们已经在__init__() 中初始化。所以我正在寻找某种方法来确定 setattr 是在类范围内还是在类范围外被调用,例如:
class MyClass:
__slots__ = ("var",)
def __init__(self):
self.__setattr__("var", 0)
def increase_val(self):
self.var += 1 # THIS SHOULD BE ALLOWED
my_obj = MyClass()
my_obj.var += 1 # THIS SHOULD BE FORBIDDEN
我的伪定义是这样的:
# pseudocode
def setattr:
if attribute in slots and scope(setattr) != MyClass:
return print("Read-only property")
super().setattr
另外,我不想将整个字典存储在一个实例变量中,因为我需要属性是不可变的。
【问题讨论】:
-
看起来应该使用name mangling 的情况很少见,但请记住,它仍然允许从类外部修改变量,这将更加困难
-
另一种选择是带有框架检查的属性
-
@DeepSpace 我觉得检查方法其实很有趣,谢谢你的建议!
标签: python scope encapsulation