Python 3 - 使用 defaultdict 的递归错误
Python 3 - RecursionError using defaultdict
我想在这里实现什么目标?
我想读取目录中的每个 .txt 文件并将它们存储到名为文档的 defaultdict 中。这个 defaultdict 的键应该是文档的名称,它的值应该是文档的内容。
请注意,某些 .txt 文件是同一文档的一部分(如新闻文章的不同页面):在这种情况下,我希望能够更新文档并在文档已存在的情况下附加 .txt 文件的内容在默认情况下。
为了做到这一点,我一直在实施这个 class:
class Document(object):
'''
Could be an article, a letter, an interview or whatever
'''
def __init__(self):
self.name = None
self.text = ''
self.image = None
@property
def name(self):
return name
@name.setter
def name(self, name):
self.name = name
def append_text(self, text):
self.text += ' ' + text
然后,我使用此函数遍历目录中的所有文件并创建 defaultdict:
def get_documents_from(dir_path):
documents = defaultdict(lambda: Document())
for filename in [f for f in os.listdir(dir_path) if f.endswith('.txt')]:
name, _ = parse_filename(filename)
documents[name].append_text(read_txt(filename))
documents[name].name = name
return documents
这里,函数parse_filename帮我获取了正在读取的文档的名称。函数 read_text returns 将文档的内容作为字符串。
当我在 main.py
中执行下面的行时
my_dir = 'path/to/directory'
documents = get_documents_from(my_dir)
我收到以下错误:
File "lda_TM.py", line 17, in <module>
documents = get_documents_from(my_dir)
File "/path/to/main.py", line 36, in get_documents_from
documents[name].append_text(read_txt(filename))
File "/path/to/main.py", line 32, in <lambda>
documents = defaultdict(lambda: Document())
File "path/to/Document.py", line 8, in __init__
self.name = None
File "path/to/Document.py", line 19, in name
self.name = name
File "path/to/Document.py", line 19, in name
self.name = name
File "path/to/Document.py", line 19, in name
self.name = name
[Previous line repeated 491 more times]
RecursionError: maximum recursion depth exceeded
我真的不明白为什么会出现此错误...是因为 class 文档未正确实施还是因为我无法将自己的对象与 defaultdict 一起使用?
我知道我可能可以通过使用一个简单的 dict 并在每次遇到新名称时创建一个新文档来解决这个问题(或者如果该名称已经存在则更新一个文档)但这似乎不是很有效并且有点不符合Python...
另外,我知道创建一个使用文档名称作为键和对象文档(已经嵌入相同名称)作为值的 defaultdict 可能看起来很奇怪。我只是想,如果我创建一个 Document 列表而不是一个 dict,我将被迫实现一个搜索功能来更新一个 Document。使用 defaultdict 似乎更有效(因为我会在读取所有文件后立即将其转换为列表)。
非常感谢您的帮助和建议!
威廉
您的 class 文档有一个属性 name
和一个 属性 name
。第二个覆盖第一个。
当你这样做时:
@property
def name(self):
return name
首先,我假设有一个错字,而不是 return self.name
,否则你会得到一个 NameError
。其次,你试图 return 是 name
的值,但现在 name
是 属性,它又试图 return 的值name
,依此类推。
典型的解决方案是将属性命名为 _name
这样它就不会被 属性.
隐藏
有关正确命名的示例,请参阅此答案:
self.name = name 递归调用 'name' 属性
这段代码可以正常工作:
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
我想在这里实现什么目标?
我想读取目录中的每个 .txt 文件并将它们存储到名为文档的 defaultdict 中。这个 defaultdict 的键应该是文档的名称,它的值应该是文档的内容。
请注意,某些 .txt 文件是同一文档的一部分(如新闻文章的不同页面):在这种情况下,我希望能够更新文档并在文档已存在的情况下附加 .txt 文件的内容在默认情况下。
为了做到这一点,我一直在实施这个 class:
class Document(object):
'''
Could be an article, a letter, an interview or whatever
'''
def __init__(self):
self.name = None
self.text = ''
self.image = None
@property
def name(self):
return name
@name.setter
def name(self, name):
self.name = name
def append_text(self, text):
self.text += ' ' + text
然后,我使用此函数遍历目录中的所有文件并创建 defaultdict:
def get_documents_from(dir_path):
documents = defaultdict(lambda: Document())
for filename in [f for f in os.listdir(dir_path) if f.endswith('.txt')]:
name, _ = parse_filename(filename)
documents[name].append_text(read_txt(filename))
documents[name].name = name
return documents
这里,函数parse_filename帮我获取了正在读取的文档的名称。函数 read_text returns 将文档的内容作为字符串。
当我在 main.py
my_dir = 'path/to/directory'
documents = get_documents_from(my_dir)
我收到以下错误:
File "lda_TM.py", line 17, in <module>
documents = get_documents_from(my_dir)
File "/path/to/main.py", line 36, in get_documents_from
documents[name].append_text(read_txt(filename))
File "/path/to/main.py", line 32, in <lambda>
documents = defaultdict(lambda: Document())
File "path/to/Document.py", line 8, in __init__
self.name = None
File "path/to/Document.py", line 19, in name
self.name = name
File "path/to/Document.py", line 19, in name
self.name = name
File "path/to/Document.py", line 19, in name
self.name = name
[Previous line repeated 491 more times]
RecursionError: maximum recursion depth exceeded
我真的不明白为什么会出现此错误...是因为 class 文档未正确实施还是因为我无法将自己的对象与 defaultdict 一起使用?
我知道我可能可以通过使用一个简单的 dict 并在每次遇到新名称时创建一个新文档来解决这个问题(或者如果该名称已经存在则更新一个文档)但这似乎不是很有效并且有点不符合Python...
另外,我知道创建一个使用文档名称作为键和对象文档(已经嵌入相同名称)作为值的 defaultdict 可能看起来很奇怪。我只是想,如果我创建一个 Document 列表而不是一个 dict,我将被迫实现一个搜索功能来更新一个 Document。使用 defaultdict 似乎更有效(因为我会在读取所有文件后立即将其转换为列表)。
非常感谢您的帮助和建议!
威廉
您的 class 文档有一个属性 name
和一个 属性 name
。第二个覆盖第一个。
当你这样做时:
@property
def name(self):
return name
首先,我假设有一个错字,而不是 return self.name
,否则你会得到一个 NameError
。其次,你试图 return 是 name
的值,但现在 name
是 属性,它又试图 return 的值name
,依此类推。
典型的解决方案是将属性命名为 _name
这样它就不会被 属性.
有关正确命名的示例,请参阅此答案:
self.name = name 递归调用 'name' 属性
这段代码可以正常工作:
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name