Python 可变基础设施:实现定制的最佳方式;“处理者”;

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

我正在为数字生活助手(有点像Siri)创建一个基础设施。应用程序应该是高度可扩展的,使用Python编写的插件。整个系统共享一个变量树。变量不是使用Python类型存储的,而是使用自定义的“变量”类型存储的。变量有getvalue和setvalue方法。例如,您可以执行
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”)。谢谢你的帮助。