Python - 使用 defaultdict 制作自定义对象的字典
Python - Using defaultdict to make dictionary of custom objects
我创建了以下 class。 Package, website 和 comments 都是字符串,distroDict 是一个 (string, list) 字典。
class TableEntry(object):
def __init__(self, package, website, distroDict, comments):
self.package = package
self.website = website
self.distroDict = distroDict
self.comments = comments
我想使用 defaultdict(TableEntry) 制作一个 (string, TableEntry) 自定义字典。
tableDict = defaultdict(TableEntry)
entry = TableEntry(package, website, distroDict, comments)
tableDict[package].append(entry)
我希望包作为键,条目对象作为值。我可以在条目对象中使用值,但如果我尝试将它附加到 tableDict,我会收到以下错误。
Traceback (most recent call last):
File "wiki.py", line 151, in <module>
printMetaData(lines, f)
File "wiki.py", line 73, in printMetaData
tableDict[package].append(entry)
TypeError: __init__() takes exactly 5 arguments (1 given)
我也试过以下方法:
tableDict[package].append(TableEntry(package, website, distroDict, comments))
并且基本上收到相同的错误:
Traceback (most recent call last):
File "wiki.py", line 150, in <module>
printMetaData(lines, f)
File "wiki.py", line 73, in printMetaData
tableDict[package].append(TableEntry(package, website, distroDict, comments))
TypeError: __init__() takes exactly 5 arguments (1 given)
当您尝试从 defaultdict 中获取某些内容时,它 returns 您实例化它的 default_factory
的实例,在您的情况下是 TableEntry
没有方法 append
。但这实际上不是您收到错误的原因。发生这种情况是因为当返回一个实例时它也被评估,并且由于 TableEntry
没有它需要的参数,Python 解释器会抱怨。但是即使 TableEntry
在 defaultdict
调用中给出了参数,你也可能会得到一个 TypeError
因为 defaultdict
需要用一个可调用的(而不是一个实例)来调用class,本来就是这样)。
总而言之,您不能使用不可调用的 unless you use subclassing 实例化 defaultdict。相反,你应该这样做:
class TableEntry(object):
def add(self, package, website, distroDict, comments):
self.package = package
self.website = website
self.distroDict = distroDict
self.comments = comments
tableDict = defaultdict(TableEntry)
entry = ("package", "website", "distroDict", "comments")
tableDict["package"].add(*entry)
然后你可以做,例如tableDict["package"]["website"]
得到你写到 self.website
.
的字符串
另一种方法是使__init__
方法的参数可选,并将条目对象直接分配给tableDict。
class TableEntry:
def __init__(self, package=None, website=None, distroDict=None, comments=None):
self.package = package
self.website = website
self.distroDict = distroDict
self.comments = comments
tableDict = defaultdict(TableEntry)
tableDict["package"] = TableEntry("package", "website", "distroDict", "comments")
我创建了以下 class。 Package, website 和 comments 都是字符串,distroDict 是一个 (string, list) 字典。
class TableEntry(object):
def __init__(self, package, website, distroDict, comments):
self.package = package
self.website = website
self.distroDict = distroDict
self.comments = comments
我想使用 defaultdict(TableEntry) 制作一个 (string, TableEntry) 自定义字典。
tableDict = defaultdict(TableEntry)
entry = TableEntry(package, website, distroDict, comments)
tableDict[package].append(entry)
我希望包作为键,条目对象作为值。我可以在条目对象中使用值,但如果我尝试将它附加到 tableDict,我会收到以下错误。
Traceback (most recent call last):
File "wiki.py", line 151, in <module>
printMetaData(lines, f)
File "wiki.py", line 73, in printMetaData
tableDict[package].append(entry)
TypeError: __init__() takes exactly 5 arguments (1 given)
我也试过以下方法:
tableDict[package].append(TableEntry(package, website, distroDict, comments))
并且基本上收到相同的错误:
Traceback (most recent call last):
File "wiki.py", line 150, in <module>
printMetaData(lines, f)
File "wiki.py", line 73, in printMetaData
tableDict[package].append(TableEntry(package, website, distroDict, comments))
TypeError: __init__() takes exactly 5 arguments (1 given)
当您尝试从 defaultdict 中获取某些内容时,它 returns 您实例化它的 default_factory
的实例,在您的情况下是 TableEntry
没有方法 append
。但这实际上不是您收到错误的原因。发生这种情况是因为当返回一个实例时它也被评估,并且由于 TableEntry
没有它需要的参数,Python 解释器会抱怨。但是即使 TableEntry
在 defaultdict
调用中给出了参数,你也可能会得到一个 TypeError
因为 defaultdict
需要用一个可调用的(而不是一个实例)来调用class,本来就是这样)。
总而言之,您不能使用不可调用的 unless you use subclassing 实例化 defaultdict。相反,你应该这样做:
class TableEntry(object):
def add(self, package, website, distroDict, comments):
self.package = package
self.website = website
self.distroDict = distroDict
self.comments = comments
tableDict = defaultdict(TableEntry)
entry = ("package", "website", "distroDict", "comments")
tableDict["package"].add(*entry)
然后你可以做,例如tableDict["package"]["website"]
得到你写到 self.website
.
另一种方法是使__init__
方法的参数可选,并将条目对象直接分配给tableDict。
class TableEntry:
def __init__(self, package=None, website=None, distroDict=None, comments=None):
self.package = package
self.website = website
self.distroDict = distroDict
self.comments = comments
tableDict = defaultdict(TableEntry)
tableDict["package"] = TableEntry("package", "website", "distroDict", "comments")