2015-12-17 2 views
3

Я создал следующий класс. Пакет, веб-сайт и комментарии - все строки, а distroDict - словарь (строка, список).Python - использование defaultdict для создания словаря пользовательских объектов

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) 
+4

Разве это не список записей в таблице, так что не хотите ли вы 'defaultdict (list)', что вы 'append'ing' TableEntry's to? По умолчанию dict ожидает функцию нулевого параметра для создания значения по умолчанию, поэтому вы фактически не можете использовать 'defaultdict (TableEntry)'. – AChampion

+0

@AChampion wouldnt 'defaultdict (list)' дайте мне dict с {string, [list]}? В то время как я ищу dict с {string, TableEntry}. Мне нужно сопоставить String с объектом, который может содержать несколько фрагментов информации и строку, список dict не будет достаточным. Если я не могу выполнить 'defaultdict (TableEntry)', как еще я мог бы это сделать? – javakid1993

+0

'defaultdist (list)' даст вам словарь {string: []}, но поскольку вы добавляете 'TableEntry' вам нужна коллекция, например. словарь {string: [TableEntry, TableEntry, ...]}. Однако, если вы просто хотите использовать словарь '{string: TableEntry}', почему вам нужен 'defaultdict', не будет' tableDict = {}; tableDict [package] = TableEntry (...) 'не работает? – AChampion

ответ

2

Когда вы пытаетесь получить что-то из defaultdict он возвращает экземпляр класса default_factory вы создали экземпляр, который в вашем случае равен TableEntry, который не имеет метода append. Но на самом деле это не то, почему вы получаете ошибку. Это происходит потому, что, когда экземпляр возвращается, он также оценивается, и поскольку TableEntry не имеет необходимых ему аргументов, интерпретатор Python будет жаловаться. Но даже если TableEntry получил аргументы в вызове defaultdict, вы, вероятно, получите TypeError, потому что defaultdict должен быть вызван с вызываемым (а не экземпляром класса, как и было).

Таким образом, вы не можете создать экземпляр defaultdict с неконтактным unless you use subclassing. Вместо этого вы должны сделать что-то вроде этого:

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.

Смежные вопросы