用于数据和重构的Python类属性
对于以下问题,我没有找到好的建议: 我正在创建一个PyQt应用程序,希望每个项目在一个文件中保存持久数据(没有serveur,没有SQL)用于数据和重构的Python类属性,python,Python,对于以下问题,我没有找到好的建议: 我正在创建一个PyQt应用程序,希望每个项目在一个文件中保存持久数据(没有serveur,没有SQL) 我决定创建一个具有属性的类,然后实例化对象。然后我将这些对象存储在一个列表中(预期
我决定创建一个具有属性的类,然后实例化对象。然后我将这些对象存储在一个列表中(预期<500个对象,大多数项目您可以执行以下操作:
class Item:
position = ['key','a','b','c']
def__init__(self, **kwargs):
for key in Item.position:
setattr(self,key,kwagrs.get(key, None))
这将使你的课堂定义很难阅读。你可以这样做:
class Item:
position = ['key','a','b','c']
def__init__(self, **kwargs):
for key in Item.position:
setattr(self,key,kwagrs.get(key, None))
这会让你很难阅读课堂违抗
item = Item(first_name='Sylvain', last_name='Page')
item = Item(first_name='Sylvain', last_name='Page')
有没有什么好的做法来代替存储实例列表?
您指定的数据量不是很高,因此类的实例列表应该是可行的,但是有更好的方法来存储这些信息
namedtuple
s的列表def Item(key=None, a=None, b=None, c=None):
return {
"key": key,
"a": a,
"b": b,
"c": c
}
额外的抽象级别增加了更多的灵活性
您甚至可以通过传递键列表来创建生成此类函数的函数:
def ItemGenerator(*spec):
def f(*args, **kwargs):
args = dict(enumerate(args))
return {k: kwargs.get(k, args.get(i, None)) for i, k in enumerate(spec)}
return f
ItemGenerator()
函数接受任意数量的字符串作为直接参数,而无需将它们包装到列表中。如果您希望只提供一个列表作为参数,只需从def ItemGenerator(*spec)中删除*
:
。它创建一个新函数,该函数返回一个字典,该字典的键是传递给ItemGenerator
的参数,其值的默认值为None
。然后它将按如下方式使用:
class Item:
position = ['key','a','b','c']
def__init__(self, **kwargs):
for key in Item.position:
setattr(self,key,kwagrs.get(key, None))
注意:python中的dict是无序的,因此在将结果打印到屏幕上时,您可能会以不同的顺序看到参数,但它们的值将被正确分配。为了清晰起见,我将它们按顺序列出
Item
函数在开始时通过指定最终字典将具有的键生成,然后可以根据需要多次使用。调用该函数时,不向生成器提供指定的参数之一会将其值设置为“无”。可以使用位置参数和命名参数,但命名参数优先。Pr提供不在规范中的额外位置参数或命名参数会自动忽略它们
更多技术说明:生成器返回一个函数,该函数捕获位置和命名(关键字)参数,并将位置参数转换为按位置索引的dict,以便能够使用dict.get(attrName,defaultValue)
。然后它使用理解返回一个dict,其键是生成器中定义的键,其值首先在命名参数中搜索,其次在位置参数中搜索,如果两者都缺失,则默认为None
。然后返回生成的函数
命名双倍
您可以使用namedtuple
(或者)而不是使用dict
,您可以使用类似的方法创建一个返回元组的函数,或者使用一个函数生成器来返回一个调用时返回namedtuple的函数。它只是更改容器
我可以自动为类指定属性吗?
是的,正如其他人回答的那样,您可以这样做:或者有没有什么好的做法来代替存储实例列表?
您指定的数据量不是很高,因此类的实例列表应该是可行的,但是有更好的方法来存储这些信息
namedtuple
s的列表def Item(key=None, a=None, b=None, c=None):
return {
"key": key,
"a": a,
"b": b,
"c": c
}
额外的抽象级别增加了更多的灵活性
您甚至可以通过传递键列表来创建生成此类函数的函数:
def ItemGenerator(*spec):
def f(*args, **kwargs):
args = dict(enumerate(args))
return {k: kwargs.get(k, args.get(i, None)) for i, k in enumerate(spec)}
return f
ItemGenerator()
函数接受任意数量的字符串作为直接参数,而无需将它们包装到列表中。如果您希望只提供一个列表作为参数,只需从def ItemGenerator(*spec)中删除*
:
。它创建一个新函数,该函数返回一个字典,该字典的键是传递给ItemGenerator
的参数,其值的默认值为None
。然后它将按如下方式使用:
class Item:
position = ['key','a','b','c']
def__init__(self, **kwargs):
for key in Item.position:
setattr(self,key,kwagrs.get(key, None))
注意:python中的dict是无序的,因此在将结果打印到屏幕上时,您可能会以不同的顺序看到参数,但它们的值将被正确分配。为了清晰起见,我将它们按顺序列出
Item
函数在开始时通过指定最终字典将具有的键生成,然后可以根据需要多次使用。调用该函数时,不向生成器提供指定的参数之一会将其值设置为“无”。可以使用位置参数和命名参数,但命名参数优先。Pr提供不在规范中的额外位置参数或命名参数会自动忽略它们
更多技术说明:生成器返回一个函数,该函数捕获位置和命名(关键字)参数,并将位置参数转换为按位置索引的dict,以便能够使用dict.get(attrName,defaultValue)
。然后它使用理解返回一个dict,其键是生成器中定义的键,其值首先在命名参数中搜索,其次在位置参数和defaul中搜索