0

私はDigitalLifeAssistant(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は子変数のVariableインスタンスを返し、getvalueは引数を受け取らず、変数が格納された型(strやintなど)を返します。

変数インスタンスがより多くのことを実行できるシステムを実装したいと思います。たとえば、現在の日時を返す変数を作成したり、Webサイトからデータをフェッチしたりできます。TwistedのDeferredのようにコールバックシステムを使用したくありません。

開発者にVariableクラスを継承させ、getvalueおよび/またはsetvalueおよび/またはgetvarメソッドをオーバーライドすることを考えましたが、これは「正しい」とは感じません。もっとエレガントな解決策があると思います。理想的には、必ずしもそうとは限りませんが、変数のgetvalueなどのメソッドは、作成後に変更/追加できます。

他のプロジェクトはこれをどのように行いますか?そのプロジェクトがこの種のことをどのように行うかを確認するために私が調べることができる他のプロジェクトはおそらくありますか?

ご協力いただきありがとうございます。

4

1 に答える 1

1

あなたの質問を読むと、変数は変更可能な値を含む階層内のノードを表しているように聞こえるので、その値を取得するための別のメカニズムを実装するために変数をサブクラス化するのは正しくないように思われることに同意します。

データ構造と 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(path、価値)。再発明するのではなく、ライブラリのツリー データ構造を使用することを検討する価値があるかもしれません。

これがあなたにいくつかのアイデアを与えることを願っています!

于 2012-12-24T20:55:19.193 に答える