我想读取目录中的每个.txt文件并将它们存储到名为documents的defaultdict中。此defaultdict的键应该是文档的名称,其值应该是文档的内容。
请注意,某些.txt文件是同一文档的一部分(就像新闻文章的不同页面一样):在这种情况下,如果文档已经存在,我希望能够更新文档并附加.txt文件的内容在违约中。
为了做到这一点,我一直在实施这个课程:
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 以字符串形式返回文档内容。
当我在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
我真的不明白为什么我会收到这个错误...是因为类文档没有正确实现,还是因为我不能使用我自己的对象和defaultdict?
我知道我可以通过使用一个简单的dict并通过每次遇到一个新名称时创建一个新文档来解决这个问题(或者如果名称已经存在则更新一个Document),但这似乎不是非常高效且有点单声道。 ..
另外,我知道创建一个defaultdict,它使用文档的名称作为键,而对象Document(已经嵌入了相同的名称)作为值可能看起来很奇怪。我只是想如果我创建了一个Document列表而不是一个dict,我将被迫实现一个搜索功能以更新Document。使用defaultdict似乎更有效(因为我会在读完所有文件后立即将其转换为List)。
非常感谢您的帮助和建议!
威廉
答案 0 :(得分:2)
您的班级文档包含属性name
和属性name
。第二个覆盖了第一个。
当你这样做时:
@property
def name(self):
return name
首先,我假设有一个拼写错误,而不是return self.name
,否则你会得到NameError
。其次,您要返回的内容是name
的值,但现在name
是属性,而后者又会尝试返回name
的值,依此类推。
典型的解决方案是将属性称为类似_name
的属性,这样它就不会被属性隐藏。
答案 1 :(得分:0)
请参阅此答案,了解正确命名的示例:https://stackoverflow.com/a/598092
self.name = name递归调用&#39; name&#39;属性
此代码正常运行:
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name