我有一个类需要从字符串中排除单词列表:
class Cleaner():
def __init__(self, remove_words=None):
self.remove_words = remove_words
def clean(self, line):
return u' '.join[word for word in line not in self.remove_words]
在主文件上,我需要读取要从行中删除的单词:
if __name__ == "__main__":
with open('remove_words') as r:
words = r.read().splitlines()
cleaning = Cleaner(words)
with open('mylines') as f:
lines = f.read()
for line in lines:
print cleaning.clean(line)
因此,我需要在创建 Clean
类之前打开 remove_words
文件。但可惜的是,我需要打开几个包含要删除的单词的文件,并且代码很快就会变得困惑。所以我添加了一个类来在Clean
类上设置可移动的单词:
class Cleaner():
def __init__(self, remove_words=None):
self.remove_words = remove_words
def set_remove_words(self, words):
self.remove_words = words
def clean(self, line):
return u' '.join[word for word in line not in self.remove_words]
现在主要代码如下所示
if __name__ == "__main__":
with open('remove_words') as r:
words = r.read().splitlines()
# after lots of these open files...
with open('remove_more_words') as r:
more_words = r.read().splitlines()
cleaning = Cleaner()
all_removable_words = words + more_worlds
cleaning.set_remove_words(all_removable_words)
with open('mylines') as f:
lines = f.read()
for line in lines:
print cleaning.clean(line)
但话又说回来,事情可能会变得非常困惑。在某些情况下,我必须打开并传递一个可移动单词列表,有时会是几个。对此的“Pythonic”解决方案是什么?是否会将带有可移动单词的文件名传递给构造函数并构建列表,这样会更“Pythonic”并且更不容易出错?应该在哪里处理异常?
最佳答案
首先,在将文件 I/O 排除在类之外方面做得很好。我喜欢你对鲍勃叔叔的干净架构原则的坚持。您绝对不应该将其移至构造函数中,因为这会将域规则代码与 open
函数耦合,从而降低其可重用性。
我会利用列表推导式和生成器来实现 Pythonic。
if __name__ == "__main__":
bad_word_sources = ['remove_words',...,'remove_more_words']
bad_word_files = (open(source) for source in bad_word_sources)
bad_words = [word for word in chain(bad_word_files)]
cleaning = Cleaner(bad_words)
这是可行的,因为 open()
函数提供了一个 __iter__
实现,其工作方式类似于
[line for line in file.readlines()]
当open
对象耗尽时,它将自行关闭[需要引用]。
我不确定您想要处理哪种类型的异常,您能具体说明一下吗?
另请注意,set_words
方法被视为 unpythonic 。如果需要,直接设置属性即可。
附注本类(class) only has 2 methods, one of which is __init__
:
class Cleaner():
def __init__(self, remove_words=None):
self.remove_words = remove_words
def clean(self, line):
return u' '.join[word for word in line not in self.remove_words]
使其可重用的 Pythonic 方法是放弃该类并将其放入模块中:
cleaner.py
def clean(line, bad_words):
return u' '.join(word for word in line if line not in self.bad_words)
然后您可以像这样使用它:
from cleaner import clean
而不是:
from cleaner import Cleaner
mycleaner = Cleaner(bad_words)
mycleaner.clean(line)
这确实令人困惑。
关于python - 读取一些文件并通过 setter 传递给构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33906423/