2017-03-06 23 views
1

私は、各プロパティが自分のデータベースにユニークな呼び出しを行う異なる名前のクラスにプロパティを動的に設定しようとしています。しかし、プロパティオブジェクトにアクセスすると、それぞれ異なる値を持つ異なる列を参照しても、すべて同じ結果が返されます。ここでは、コードは次のとおり異なる関数、同じ結果

class Configs: 

    def __init__(self, guild_id): 
     self.guild_id = guild_id 

for x in configs: 

    def fget(self): 
     return cur.execute(f'SELECT {x.name} FROM configs WHERE guild_id = ?', (self.guild_id,)).fetchone()[0], x.name 

    def fset(self, value): 
     cur.execute(f'UPDATE configs SET {x.name} = ? WHERE guild_id = ?', (value, self.guild_id)) 
     con.commit() 

    setattr(Configs, x.name, property(fget, fset)) 

コンフィグ変数は、各オブジェクトが文字列を指すname属性を有するオブジェクトのリストです。結果は常にconfigs配列の最後の要素が生成する結果であり、x.nameが呼び出しに使用され、forループが完了するとxは配列の最後の要素として残りますので、これが起こっていると思われます。

+0

'X'とは何ですか?それは 'Configs'ですか? 'x.name'の値はどこで設定しますか? – khelwood

+1

'x'は、文字列があらかじめ割り当てられている単一の' name'属性を持つ単純なオブジェクトです。私はコードの別の部分でこれらのオブジェクトを構築しています。 'configs'は、これらのオブジェクトが3つ以上あるリストです。 – Exa

+0

これは、アクセスされたときにデータベースから読み書きする 'x.name'の値が何であるかという名前のプロパティを設定しようとしていますか?アクティブなレコードのように? – khelwood

答えて

1

関数を定義すると、定義時に関数が変数値にバインドされるという誤った印象を受けています。これは複雑です、申し訳ありません。私は説明しようとします。

関数をループで定義しています(fgetfset)。関数では、ループの変数(x)を使用します。これはうまくいくが、あなたが期待している通りではない。すべての関数は全く同じになり、呼び出し時にグローバル変数xの値に常にアクセスします。定義時の値は考慮されません。

この例を参照してください:

a = [] 
for i in range(3): 
    def f(): return i 
    a.append(f) 

a[0]() # will return 2 
del i 
a[0]() # will raise a NameError because there is no i anymore 

あなたの問題を解決するために、あなたが関数に定義する時に値を渡す必要があります。

def fget(self, x=x): 
    return cur.execute(f'SELECT {x.name} FROM configs WHERE guild_id = ?', (self.guild_id,)).fetchone()[0], x.name 

def fset(self, value, x=x): 
    cur.execute(f'UPDATE configs SET {x.name} = ? WHERE guild_id = ?', (value, self.guild_id)) 
    con.commit() 
0

私が行っていることに従えば、あなたのプロパティが呼び出されたときには、現在の値がx.nameであるものが使用されることは間違いありません(これは最後に残っていますあなたのループ)。

これを修正する方法は次のとおりです。x.nameに、プロパティ関数がアクセスできる別の変数を割り当てます。デフォルトの引数がうまくいくかもしれません。

関連する問題