想到的特定示例是文件名及其大小的列表。我不能决定列表中的每个项目是否应该是这样的形式{"filename": "blabla", "size": 123}
,或者只是("blabla", 123)
。字典对我来说似乎更合乎逻辑,因为例如访问大小file["size"]
比file[1]
... 更具解释性,但是我不确定。有什么想法吗?
想到的特定示例是文件名及其大小的列表。我不能决定列表中的每个项目是否应该是这样的形式{"filename": "blabla", "size": 123}
,或者只是("blabla", 123)
。字典对我来说似乎更合乎逻辑,因为例如访问大小file["size"]
比file[1]
... 更具解释性,但是我不确定。有什么想法吗?
Answers:
我会使用namedtuple
:
from collections import namedtuple
Filesize = namedtuple('Filesize', 'filename size')
file = Filesize(filename="blabla", size=123)
现在,您可以在程序中使用file.size
和file.filename
,这是恕我直言最易读的形式。注namedtuple
会建立像元组不可变对象,和他们比字典更轻巧,描述在这里。
Filesize = namedtuple('Filesize', 'filepath kilobytes')
attrs
模块(可以通过找到它pip
或只是搜索它),它使您具有与命名元组非常相似的语法便利,但可以赋予您可变性(但也可以使其不可变)。功能上的主要区别是attrs
-made类与namedtuple
s 相比不等于普通元组。
namedtuple
实际上是具有不可变属性的新类型的简短说明。这意味着答案实际上是“既不是a tuple
也不是a dict
,而是an” object
。+1
{“ filename”:“ blabla”,“ size”:123},或者只是(“ blabla”,123)
这是对带内或带外格式/模式进行编码的古老问题。
您需要权衡一些内存,以从在数据中正确表达数据格式来获得可读性和可移植性。如果您不这样做,则必须知道第一个字段是文件名,第二个字段是大小,必须将其保留在其他位置。这样可以节省内存,但会降低可读性和可移植性。哪个会花费您的公司更多的钱?
至于不可变的问题,记住不可变并不意味着面对变化就没有用。这意味着我们需要获取更多的内存,在副本中进行更改,然后使用新副本。这不是免费的,但通常不是交易突破者。我们始终使用不可变的字符串来更改内容。
另一个考虑因素是可扩展性。当您仅按位置存储数据而没有对格式信息进行编码时,那么您将只能使用单继承,这实际上只是在已建立的字段之后串联其他字段的做法。我可以将第三个字段定义为创建日期,并且仍然与您的格式兼容,因为我以相同的方式定义了第一和第二个字段。
但是,我不能做的是将两个独立定义的格式组合在一起,这些格式具有一些重叠的字段,有些则没有,将它们存储为一种格式,并且对仅了解一种或另一种格式的东西很有用。
为此,我需要从一开始就对格式信息进行编码。我需要说“此字段是文件名”。这样做可以实现多重继承。
您可能习惯了仅在对象的上下文中表示继承,但是相同的思想也适用于数据格式,因为对象存储在数据格式中。这是完全一样的问题。
因此,请使用您认为最需要的东西。除非我有充分的理由不这样做,否则我会保持灵活性。
我将使用具有两个属性的类。file.size
比file[1]
或更好file["size"]
。
简单胜于复杂。
file = Filesize(filename='stuff.txt', size=222)
并且filetup = ("stuff.txt", 222)
都生成相同的JSON:json.dumps(file)
并json.dumps(filetup)
导致:'["stuff.txt", 222]'
文件名是否唯一?如果是这样,您可以完全删除列表,而仅对所有文件使用纯字典。例如(假设的网站)
{
"/index.html" : 5467,
"/about.html" : 3425,
"/css/main.css" : 9876
}
等等...
现在,您无需使用“名称”和“大小”,而只使用键和值,但这通常更自然。YMMV。
如果您确实需要一个“大小”来简化说明,或者该文件需要多个值,则:
{
"/index.html" : { "size": 5467, "mime_type" : "foo" },
"/about.html" : { "size": 3425, "mime_type" : "foo" }
"/css/main.css" : { "size": 9876, "mime_type" : "bar" }
}
fname, file_size = file
如果数据在元组上方,则该元组将被删除file[1]
并替换为file_size
。当然,这取决于良好的文档。