1

各変数が値と説明で構成される「環境」を作成しています。

class my_var:
   def __init__(self, value, description):
      self.value = value
      self.description = description

変数が作成され、辞書内に配置されます。

my_dict["foo"] = my_var(0.5, "A foo var")

これはクールですが、変数を使用した操作の 99% は「値」メンバーを使用しています。だから私はこのように書かなければなりません:

print my_dict["foo"].value + 15  # Prints 15.5

また

my_dict["foo"].value = 17

オブジェクト my_dict["foo"] に対するすべての操作がデフォルトで "value" メンバーになるようにしたいと思います。言い換えれば、私は書きたい:

print my_dict["foo"] + 15     # Prints 5.5

などなど。

私が見つけた唯一の方法は、すべてのアンダースコア メンバー (eq、add、str など)を再実装することですが、これはどういうわけか間違った方法のように感じます。私が使える魔法の方法はありますか?

回避策は、次のように辞書を増やすことです。

my_dict_value["foo"] = 0.5
my_dict_description["foo"] = "A foo var"

しかし、私はこの解決策が好きではありません。何か提案はありますか?

4

4 に答える 4

3

2 つの一般的な注意事項。

  1. クラス名には大文字を使用してください。

  2. (Python 3.0 を使用しない限り) オブジェクトをサブクラス化してください。 class My_Var(object):、 例えば。

今あなたの質問に。

そうだとしましょう

x= My_Var(0.5, "A foo var")

xPythonは、複合オブジェクトと x の値 ( ) をどのように区別しx.valueますか?

次の動作が必要ですか?

  • x複合オブジェクト全体を意味する こともあります。

  • xを意味する場合もx.valueある。

2つをどのように区別しますか?あなたが何を意味しているのかをPythonにどのように伝えますか?

于 2009-04-10T12:59:31.350 に答える
2

http://docs.python.org/reference/datamodel.htmlのセクション「数値型のエミュレート」で演算子を実装することにより、ほとんどが「値」のように機能するが追加の属性「説明」を持つオブジェクトを作成できます。

class Fooness(object):
    def __init__(self,val, description):
        self._val = val
        self.description = description

    def __add__(self,other):
        return self._val + other

    def __sub__(self,other):
        return self._val - other

    def __mul__(self,other):
        return self._val * other

    # etc

    def __str__(self):
        return str(self._val)


f = Fooness(10,"my f'd up fooness")
b = f + 10
print 'b=',b
d = f - 7
print 'd=',d

print 'f.description=',f.description

プロデュース:

b= 20
d= 3
f.description= my f'd up fooness
于 2009-04-10T13:03:45.927 に答える
2

個人的には、値用と説明用の 2 つの辞書を使用します。魔法の振る舞いに対するあなたの欲求は、あまり Pythonic ではありません。

そうは言っても、独自の dict クラスを実装できます。

class DescDict(dict):
    def __init__(self, *args, **kwargs):
        self.descs = {}
        dict.__init__(self)

    def __getitem__(self, name):
        return dict.__getitem__(self, name)

    def __setitem__(self, name, tup):
        value, description = tup
        self.descs[name] = description
        dict.__setitem__(self, name, value)

    def get_desc(self, name):
        return self.descs[name]

このクラスは次のように使用します。

my_dict = DescDict()
my_dict["foo"] = (0.5, "A foo var")  # just use a tuple if you only have 2 vals
print my_dict["foo"] + 15            # prints 15.5
print my_dict.get_desc("foo")        # prints 'A foo var'

魔法のような行動を取ることにした場合、これは良い出発点になるはずです。

于 2009-04-10T13:06:11.600 に答える
1

派手なショートカットを作るために多くの作業をしなければならないという事実は、あなたが方向性に逆行していることを示していると思います. あなたがしていることは LSP に違反しています。それは直感に反します。

my_dict[k] = v;
print my_dict[k] == v # should be True

dict の意味を変更するよりも、2 つの別個の dict でさえ望ましいでしょう。

于 2009-04-10T12:58:38.637 に答える