Python 读取一些文件并由setter传递给构造函数

Python 读取一些文件并由setter传递给构造函数,python,Python,我有一个类需要从字符串中排除一个单词列表: 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] 在主文件中,我需要阅读要从行中删除的单词:

我有一个类需要从字符串中排除一个单词列表:

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进入课堂的工作。我喜欢你坚持Bob叔叔的干净架构原则。您绝对不应该将其移动到构造函数中,因为这会将域规则代码耦合到
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()

[line for line in file.readlines()]
打开
对象耗尽时,它将自行关闭[需要参考]

我不知道你想处理哪种例外情况,你能更具体地说一下吗

还要注意的是,考虑了
set_单词
方法。如果必须,只需直接设置属性


在本课程的旁注中:

使其可重用的python方法是抛弃类并将其放入模块中:

清洁剂.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)
这真让人困惑

有些情况下,我只能打开并传递一个可移动单词列表,有时会是几个。对于这个问题,什么是“pythonic”解决方案

我认为您需要的是动态参数/参数

class Cleaner():
     def __init__(self, *remove_words):
         self.remove_words = []
         [self.remove_words.extend(one) for one in remove_words]

     def clean(self, line):
         return u' '.join[word for word in line not in self.remove_words]

还有另一种方法,**argw,用于关键字参数,您可以为参数dict指定名称。

您的类
Cleaner
Clean
也是这样吗?您似乎正在实现一个
Cleaner
类,但启动了
Clean
对象……我认为如果您只想添加更多的单词,可以使用
list.extend(otherlist)
并定义一个
add\u more\u words
函数,该函数接收列表并调用类似于
remove\u words.extend(more\u words)
的函数。这意味着使用一个默认值,即空列表而不是
None
,这样,如果您在没有列表的情况下启动对象,它就可以工作。此外,我会使用
set()
而不是列表,因为它们更有效地检查值是否在集合中。谢谢!我喜欢用生成器读取文件的方法。模块的问题是1。这个类有更多的方法和2。我正努力用一个输入来保存这些方法,因为我需要用pandas的
applymap
方法来应用这些方法,如果只有一个参数,就会容易得多。顺便说一句,停止编写类的链接很棒。你可以使用
Functionools.partial
来实现这一点:)
class Cleaner():
     def __init__(self, *remove_words):
         self.remove_words = []
         [self.remove_words.extend(one) for one in remove_words]

     def clean(self, line):
         return u' '.join[word for word in line not in self.remove_words]