2

質問

私は次のことを達成したい:

tmp = do_stuff(tmp2)
if tmp != None:
    num = tmp

ただし、私の問題で割り当てられる変数は、オブジェクト インスタンスの変数 (より良い: プロパティ) です。

class mycls(object):
    def __init__(self):
        self.__a, self._b, self.c = 2, 3, 5
    def set_a(self, val): self.__a = val
    def set_b(self, val): self._b = val
    def set_c(self, val): self.c = val
    A = property(fset = set_a)
    B = property(fset = set_b)
    C = property(fset = set_c)
tmp2 = [7, 11, 13]
inst = mycls()
tmp = do_stuff(tmp2[0])
if tmp != None: inst.A = tmp
tmp = do_stuff(tmp2[1])
if tmp != None: inst.B = tmp
tmp = do_stuff(tmp2[2])
if tmp != None: inst.C = tmp

明らかに、最後の部分は非常に反復的に見え、私の場合は 10 を超える変数に適用する必要があります。私の質問は次のとおりです。これらの最後の6行をどのように圧縮できますか?

問題を解決するための独自の試み

理想的には、次のようなソリューションを好みます。

for i in [[inst.A, 0], [inst.B, 1], [inst.C, 2]]:
    tmp = do_stuff(tmp2[i[1]])
    if tmp != None: i[0] = tmp

ただし、これは機能しません (inst.Xが評価され、参照/ポインターによってプリミティブ データ型を格納できないため)。私が思いついた別のアプローチは、変数名を文字列として使用し、inst.__dict__次のようにいじることでした。

for i in [["A", 0], ["B", 1], ["C", 2]]:
    tmp = do_stuff(tmp2[i[1]])
    if tmp != None: inst.__dict__[i[0]] = tmp

Aしかし、この計画は、BCがプロパティであるという事実によって失敗に終わりました。

LISP のようなマクロはここで非常に役立ちますが、残念ながら Python はマクロをサポートしていないようで、オンラインで見つけた Python のマクロ ライブラリの 1 つに依存関係を追加したくありません (テストしていないため、テストしていません)。いずれにせよ、私はそれらを使用することはできません)。

また、リストで無名関数を使用することは避けたいと考えています。これは、2 番目のコード リストと同じ量のコードになる可能性が高いためです。

この問題を解決するための最後の手段は、現時点ではevals です。

4

1 に答える 1

6

あなたが探しているsetattr()

for i in [["A", 0], ["B", 1], ["C", 2]]:
    tmp = do_stuff(tmp2[i[1]])
    if tmp != None: setattr(inst, i[0], tmp)

ドキュメントを引用するには:

これは の対応物ですgetattr()。引数は、オブジェクト、文字列、および任意の値です。文字列には、既存の属性または新しい属性の名前を付けることができます。オブジェクトで許可されている場合、この関数は属性に値を割り当てます。たとえば、setattr(x, 'foobar', 123)は と同等x.foobar = 123です。

NonePython ではシングルトンであるため、通常はisoris not演算子を使用してテストすることに注意してください。

for i in [["A", 0], ["B", 1], ["C", 2]]:
    tmp = do_stuff(tmp2[i[1]])
    if tmp is not None:
        setattr(inst, i[0], tmp)

また、PEP 8 python スタイルガイドは、複合ステートメントを推奨していません。ifたとえ 1 行であっても、スイートを独自の行に保持します。

于 2012-08-25T14:30:44.843 に答える