我正在尝试找到一种方法来设置封装在dict
中的class
值,例如使用__getattr__
我可以返回内部dict
值,但是{即使属性存在,也会调用{1}},这使得我的实现很难看。以下示例简化了我的实际类继承自__setattr__
Subject
(观察者模式的主题部分)
我正在努力实现这样的目标:
class
我问的是否有比我下面的方式更好的方式:
obj = Example()
obj.username = 'spidername' # all OK username is a key in the internal dict
# but company is not a key in the internal dict so
obj.company = 'ABC' # will raise AttributeError
编辑:调整了代码中的评论,添加了missin引号
答案 0 :(得分:3)
问题是首次分配属性时不存在这些属性。在__init__
中,当您首次将字典分配给_fields
时,_fields
不是属性。它仅在分配后成为现有属性。如果您事先知道属性是什么,则可以使用__slots__
,但我的猜测是您没有。所以我的建议是手动将这些插入到实例dict中:
class Example(object):
def __init__(self, table=None):
self.__dict__['_fields'] = {}
self.__dict__['_table'] = table
...
def __setattr__(self, name, value):
if name in self._fields:
self._fields[name].value = value
else:
raise AttributeError
但是,通过此实现,以后可以通过__dict__
添加或更改实例属性的唯一方法。但我认为这不太可能。
答案 1 :(得分:2)
FWIW,您的总体目标只需使用__slots__:
即可直接实现>>> class Example(object):
__slots__ = ['username']
>>> obj = Example()
>>> obj.username = 'spiderman'
>>> obj.company = 'ABC'
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
obj.company = 'ABC'
AttributeError: 'Example' object has no attribute 'company'