在 python 中,我可以通过直接分配给属性或通过调用改变属性状态的方法来改变实例的状态:
foo.thing = 'baz'
或者:
foo.thing('baz')
有没有一种很好的方法来创建一个可以接受上述两种形式的类,这些形式可以扩展到大量以这种方式运行的属性?(简而言之,我将展示一个我不太喜欢的实现示例。)如果您认为这是一个愚蠢的 API,请告诉我,但也许需要一个更具体的示例。说我有Document
课。 Document
可以有一个属性title
。但是,title
可能也希望有一些状态(字体,字体大小,对齐,...),但普通用户可能会很高兴只需将标题设置为字符串并完成它......
实现此目的的一种方法是:
class Title(object):
def __init__(self,text,font='times',size=12):
self.text = text
self.font = font
self.size = size
def __call__(self,*text,**kwargs):
if(text):
self.text = text[0]
for k,v in kwargs.items():
setattr(self,k,v)
def __str__(self):
return '<title font={font}, size={size}>{text}</title>'.format(text=self.text,size=self.size,font=self.font)
class Document(object):
_special_attr = set(['title'])
def __setattr__(self,k,v):
if k in self._special_attr and hasattr(self,k):
getattr(self,k)(v)
else:
object.__setattr__(self,k,v)
def __init__(self,text="",title=""):
self.title = Title(title)
self.text = text
def __str__(self):
return str(self.title)+'<body>'+self.text+'</body>'
现在我可以按如下方式使用它:
doc = Document()
doc.title = "Hello World"
print (str(doc))
doc.title("Goodbye World",font="Helvetica")
print (str(doc))
这个实现看起来有点混乱(使用__special_attr
)。也许那是因为这是一个混乱的 API。我不确定。 有一个更好的方法吗? 还是我在这条路上走得太远了?
我意识到我也可以使用@property
它,但是如果我有多个属性以这种方式运行,那根本无法很好地扩展——我需要为每个属性编写一个 getter 和 setter,哎呀。