2017-08-21 8 views
0

私は複数の辞書変数を持つクラスを持っています。変数名が関数内の文字列として渡されるクラス変数の辞書パラメータを設定する方法はありますか? " '自己' はunsubscriptableです":Python: 'self'はunsubscriptableです

<?php 
class Test: 
    var1 = { "value": 1 } 
    var2 = { "value": 2 } 

    def set_variable(self, var_name, value): 
     ## self.var_name.value = value ### pylint: Instance of 'Test' has no 'var_name' member 
     self[var_name]["value"] = value ### pylint: 'self' is unsubscriptable ### 

instance = Test() 
instance.set_variable("var1", 150) 

リンターをコーディング中は、というエラーがスローされます。私がコードを実行すると、エラーが出ます: "TypeError: 'Test'オブジェクトは添字付きではありません。この問題を解決するために

一つの方法は、「GETATTR」を使用して、一時的な変数を作成することである:

def set_variable(self, var_name, value): 
     temp = getattr(self, var_name) 
     temp["value"] = value 
     setattr(self, var_name, temp) 

しかし、私は上記の、特にはるかに大きい辞書のためのメモリ使用量を増やす醜い解決策であることがわかりました。

また、self [var_name]を多くの場所で使用したいと思います。これを行う方法はありますか?

+0

オーバーライド '__getitem__'と' __setitem__' – thebjorn

+0

を? –

+0

set_variableはクラスメソッドです!コードを読んでいないのですか? –

答えて

0

setattr(self, var_name, temp)は、元の辞書(しばらくの間tempと名前を付ける)を変更しているため、不要です。ここでは本質的にノーオペレーションです(あなたが読んだ辞書の同じアドレスを設定しています)。したがって、メモリ使用量は小さく、辞書の大きさには依存しません。

ですからに近かった解決策は以下のとおりです。

def set_variable(self, var_name, value): 
    getattr(self, var_name)["value"] = value 
0

あなたがやりたいself.__dict__[var_name]を使用することができます。

1

Pythonクラスはディクショナリを使用して実装されますが、ディクショナリとして辞書として扱うことはできません。

self[var_name]は、getattr(self, var_name)である必要があります。

あなたは[ ]構文Testを使用して主張する場合__getitem__実装する必要があります。VAR1とVAR2は、クラスメソッドをset_variableされていない理由クラス変数、ある場合

class Test: 
    var1 = { "value": 1 } 
    var2 = { "value": 2 } 

    def set_variable(self, var_name, value): 
     self[var_name]["value"] = value 
     # or getattr(self, var_name)["value"] = value if not implementing __getitem__ 

    def __getitem__(self, item): 
     return getattr(self, item) 

instance = Test() 
instance.set_variable("var1", 150) 
print(instance.var1) 
# {'value': 150} 
+0

__getitem__を使うと完璧に見えます。ありがとう:) –

関連する問題