不同的功能,相同的结果
问题描述:
所以我试图动态地设置属性到不同名称的类,其中每个属性对我的数据库进行独特的调用。但是,当我访问属性对象时,尽管在不同的列上查看了各自完全不同的值,但它们都返回相同的结果。下面是代码:不同的功能,相同的结果
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))
的CONFIGS变量是对象的列表,其中每个对象具有一个name
属性,它指向一个字符串。结果始终是configs数组的最后一个元素产生的结果,我怀疑这是因为x.name
用于调用,一旦for循环完成,x仍然是数组的最后一个元素。
答
你有一种错误的印象,即定义一个函数将函数绑定到定义时的变量值。这听起来很复杂,对不起。我会尽力解释。
您正在循环中定义函数(fget
,fset
)。在函数中使用循环变量(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()
答
如果我遵循你正在尝试做的事情,那么当你的属性被调用时,他们会使用任何当前的值x.name
(这将是在结束时剩下的任何东西)你的循环)。
以下是解决该问题的一种可能方法:将x.name
分配给您的属性功能可以访问的另一个变量。默认参数可能适用于此。
for x in configs:
def fget(self, col_name=x.name):
return cur.execute(f'SELECT {col_name} FROM configs WHERE guild_id = ?', (self.guild_id,)).fetchone()[0], col_name
def fset(self, value, col_name=x.name):
cur.execute(f'UPDATE configs SET {col_name} = ? WHERE guild_id = ?', (value, self.guild_id))
con.commit()
setattr(Configs, x.name, property(fget, fset))
什么是'x'?它是一个'Configs'吗?你在哪里设置'x.name'的值? – khelwood
'x'是一个简单的对象,带有一个'name'属性,它有一个预先分配给它的字符串。我在代码的另一部分构建这些对象。 'configs'只是一个包含3个或更多这些对象的列表。 – Exa
所以你试图设置一个属性,称为“x.name”的值,它在访问数据库时从数据库中读取和写入?像一个活跃的记录? – khelwood