我正在为数字生活助手创建一个基础设施(有点像Siri)。应用程序应该是高度可扩展的,使用Python编写的插件。整个系统共享一个变量树。变量不是使用Python类型存储的,而是使用自定义的“变量”类型。变量有getvalue和setvalue-methods。你可以做var=Variable();var.setvalue('child1','thisvalue')
,还有var.setvalue('child1.child2','othervalue')
。
要检索值var.getvar('child1.child2').getvalue()
,还要检索var1=var.getvar('child1');var1.getvar('child2').getvalue()
。 Getvar返回一个子变量的变量实例,getvalue不带参数,并返回存储变量的类型(例如str或int)。
我想实现一个系统,其中一个Variable实例可以做更多的事情:例如,可以创建一个返回当前日期时间的变量,或者从网站获取一些数据。我不想使用像Twisted's Deferred那样的回调系统。
我考虑让开发人员继承Variable类,并覆盖getvalue和/或setvalue和/或getvar方法,但是,这感觉不对“正确”。我认为这是一个更优雅的解决方案。理想情况下,但不一定,可以在创建后更改/添加Variable的getvalue等方法。
其他项目如何做到这一点?是否有一些其他项目我可以查看该项目是如何做到这一点的?
感谢您的帮助。
答案 0 :(得分:1)
从阅读你的问题来看,听起来变量代表你的层次结构中包含可变值的节点,所以我同意将Variable子类化以实现获取其值的不同机制似乎是不对的。
忽略数据结构和get / set接口,我建议使用这种架构:
class Variable(object):
def __init__(self, value=None):
if value is not None and not isinstance(value, ValueProducer):
raise TypeError("Expected a ValueProducer.")
self.__value = value
def getValue(self):
return self.__value.produce() if self.__value else None
def setValue(self, value):
if value is not None and not isinstance(value, ValueProducer):
raise TypeError("Expected a ValueProducer.")
self.__value = value
class ValueProducer(object):
def produce(self):
raise NotImplementedError()
class SimpleValueProducer(ValueProducer):
def __init__(self, value):
self.__value = value
def produce(self):
return self.__value
class HttpRequestValueProducer(ValueProducer):
def __init__(self, url, params, method="GET"):
self.__url = url
self.__params = params
self.__method = method
def produce(self):
# Implementation omitted.
return "Stub for HTTP request: " \
+ ", ".join((self.__url, str(self.__params), self.__method)
>>> v1 = Variable(SimpleValue("foo"))
>>> print v1.getValue()
foo
>>> v1.setValue(HttpRequestValue("http://localhost:8080", {"bar": "baz"}))
>>> print v1.getValue()
Stub for HTTP request: http://localhost:8080, {'bar': 'baz'}, GET
>>> v1.setValue("test")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test3.py", line 13, in setValue
raise TypeError("Expected a ValueProducer.")
TypeError: Expected a ValueProducer.
>>> v2 = Variable()
>>> print v2.getValue()
None
我将ValueProducer的类与实现其接口的子类一起使用的原因是为了提升一些可重用性,特别是对于需要大量代码检索的值。
另外,在你的问题中获取和设置值的路径语法似乎有点尴尬:找到一个节点并直接设置它的值感觉更自然,而不是在parent.setValue中组合搜索和设置操作。 (路径,价值)。可能值得研究使用库中的树数据结构而不是重新发明它。
希望这会给你一些想法!