Python 可变基础设施:实现定制的最佳方式;“处理者”;
我正在为数字生活助手(有点像Siri)创建一个基础设施。应用程序应该是高度可扩展的,使用Python编写的插件。整个系统共享一个变量树。变量不是使用Python类型存储的,而是使用自定义的“变量”类型存储的。变量有getvalue和setvalue方法。例如,您可以执行Python 可变基础设施:实现定制的最佳方式;“处理者”;,python,variables,plugins,architecture,Python,Variables,Plugins,Architecture,我正在为数字生活助手(有点像Siri)创建一个基础设施。应用程序应该是高度可扩展的,使用Python编写的插件。整个系统共享一个变量树。变量不是使用Python类型存储的,而是使用自定义的“变量”类型存储的。变量有getvalue和setvalue方法。例如,您可以执行var=Variable();var.setvalue('child1','thisvalue') ,但也var.setvalue('child1.child2','othervalue')。 检索值var.getvar('chi
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)
我想实现一个系统,其中变量实例可以做更多的事情:例如,可以创建一个返回当前日期时间的变量,或者从网站获取一些数据。我不想像Twisted的Deferred那样使用回调系统
我曾考虑让开发人员只继承变量类,并重写getvalue和/或setvalue和/或getvar方法,但是,这感觉不“正确”。我认为有一个更优雅的解决方案。理想情况下(但不一定),可以在创建后更改/添加变量的getvalue等方法
其他项目如何做到这一点?是否有其他项目我可以研究一下,看看这个项目是如何做到这一点的
感谢您的帮助。通过阅读您的问题,听起来变量代表层次结构中包含可变值的节点,因此我同意,为了实现获取其值的不同机制而对变量进行子类化似乎是不对的 忽略数据结构和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
类变量(对象):
def u u init u u;(self,value=None):
如果值不是None且不是isinstance(值、值生产者):
raise TYPE ERROR(“应为ValueProducer。”)
自我价值=价值
def getValue(自身):
返回self.\u value.product()如果self.\u value否则无
def设置值(自身,值):
如果值不是None且不是isinstance(值、值生产者):
raise TYPE ERROR(“应为ValueProducer。”)
自我价值=价值
类别ValueProducer(对象):
def生产(自):
引发未实现的错误()
类SimpleValueProducer(ValueProducer):
定义初始值(自身,值):
自我价值=价值
def生产(自):
返回self.\u值
类HttpRequestValueProducer(ValueProducer):
定义初始化(self,url,params,method=“GET”):
self.\uu url=url
self.\u params=参数
self.\uu方法=方法
def生产(自):
#省略了实现。
返回“HTTP请求的存根:”\
+“,”.join((self.\uuu url,str(self.\uu参数),self.\uu方法)
>>>v1=变量(SimpleValue(“foo”))
>>>打印v1.getValue()
福
>>>v1.设置值(HttpRequestValue(“http://localhost:8080“,{bar:“baz”}”)
>>>打印v1.getValue()
HTTP请求的存根:http://localhost:8080,{'bar':'baz'},快
>>>v1.设定值(“测试”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
setValue中第13行的文件“test3.py”
raise TYPE ERROR(“应为ValueProducer。”)
TypeError:应为ValueProducer。
>>>v2=变量()
>>>打印v2.getValue()
没有一个
我之所以使用ValueProducer类以及实现其接口的子类,是为了提高一些可重用性,特别是对于需要大量代码才能检索的值
另一方面,问题中获取和设置值的路径语法似乎有点笨拙:直接查找节点并设置其值比在parent.setValue(path,value)中组合搜索和设置操作感觉更自然。使用图书馆中的树型数据结构可能值得研究,而不是重新设计
希望这能给你一些想法!我真的很喜欢你的解决方案。将特殊处理程序视为对象比我最初计划的函数直观得多。通过这种方式(使用对象),它类似于Pythons的内置类型(例如,“该变量是int”或“该变量是HttpRequest”)。谢谢你的帮助。