【问题标题】:How can I make an iterable object (list of lists) from a csv file, using the OOP format?如何使用 OOP 格式从 csv 文件创建可迭代对象(列表列表)?
【发布时间】:2019-01-26 21:35:15
【问题描述】:

作为学习 OOP 的练习,我试图将现有脚本转换为 OOP 形式,但没有成功:我当前的 OOP 方法创建了一个不可迭代的对象 ma​​in.rawText 对象位于 0x0000029D55515BA8> TypeError: 'rawText' 对象不可迭代

我练习的目的是将 CSV 文件(产品评论的集合)中的内容读取到将被清理和分析的列表列表中。如何生成可以进行列表和文本操作的列表?

下面的第一个脚本是我失败的尝试,之后是工作的非 OOP 版本

class rawText(object):
        def __init__(self, name_file):
                self.name_file = name_file

        def read_file(self):
                """Read the file concent"""

                with open(name_file, 'r') as in_file:
                    self = in_file.readlines()
                return self

        def display_file(self):
                print(self)

def main():
        x = rawText('HCPsentiment2.csv')
        x.display_file()

if __name__ == '__main__':
        main()

上面产生了一些我无法运行 content_cleaner 的东西。下面是我的原...

# Step 1A - define the content cleaner
def content_cleaner(feed_list):
    temp_list = [str(item) for item in feed_list]
    temp_list = [item.lower() for item in temp_list]
    temp_list = [item.replace("b\'","").replace("\\x93","").replace("\\x94","").replace("\\x96","")
            .replace('.','').replace(',','').replace(';','').replace(':','').replace('(','').replace(')','')                .replace("'\'","").replace("\\x92","'").replace('"','').replace('"','').replace('[','').replace(']','')
            .replace("\\","'")
             for item in temp_list]
    return list(filter(None, temp_list))

# Step 1B - draw in raw sample text (here a pre-screened csv file)
with open('HCPsentiment2.csv', 'rb') as file:
    content = file.readlines()
    # perform transformation
    content_clean = content_cleaner(content)

# Step 1C - split and clean the sample
content_cl_sp=[phrase.split() for phrase in content_clean]
content_flat = [item for sublist in content_cl_sp for item in sublist]

【问题讨论】:

  • self = in_file.readlines() ?你觉得这有什么作用? self 是你类的 instance .. 你为什么要给它分配一些东西?
  • open('HCPsentiment2.csv', 'rb') ... 为什么将 text 读为 "rb" 二进制?
  • 为什么都是item.replace("b\'","").replace("\\x93","").replace("\\x94","").replace("\\x96","") .replace('.','').replace(',','').replace(';','').replace(':','').replace('(','').replace(')','') .replace("'\'","").replace("\\x92","'").replace('"','').replace('"','').replace('[','').replace(']','').replace("\\","'")
  • ... 是否会使用模块 csv 或 pandas 或其他任何东西来阅读您的 csv 尊重引用的字符串不会让它变得更容易吗? CSV 读取很简单,看看 f.e.这里:how-to-read-csv-file-lines-and-split-elements-in-line-into-list-of-lists
  • 感谢您的回复,帕特里克。作为对所有问题的一般回答:我对编程、python 和 OOP 比较陌生。具体来说...... 1. 我认为 self = in_file.readlines() 会创建一个阅读器对象(我从你的回复中不清楚这个假设是否正确)。 2. 'rb' 是一个错字 3. replace 语句从文本中删除了一堆垃圾 4. 后面的元素(未显示)涵盖了一些与 pandas 相关的评论

标签: python python-3.x oop


【解决方案1】:

您需要指定特殊方法(__next____iter__)以使类本身可迭代。

签名

self = in_file.readlines()

不起作用 - 它替换了 self 指向的任何东西(在它是你的类的实例之前 - 之后它是一个行列表) - 这不会改变你保存类实例的其他变量。


如果您的 csv 很小,并且您可以将所有数据保存在类本身中,您可以在文件中读取并将其存储在类中:

class rawText(object):
    def __init__(self, name_file):
        self.name_file = name_file
        self.lines = None
        self.idx = 0

    def read_file(self):
        """Read the file concent and store inside class instance"""
        with open(self.name_file, 'r') as in_file:
            self.lines = [x.rstrip() for x in in_file.readlines()]
        return self.lines

    def __next__(self):
        if not self.lines:
            self.read_file()
        try: 
            self.idx += 1
            return self.lines[self.idx - 1].rstrip() 
        except IndexError:
            raise StopIteration

    def __iter__(self): 
        return self

    # replaces your display_file
    def __str__(self):
        return self.name_file + (" : " if self.lines else "") + (
                                 "    ".join(self.lines or []))

用法:

rt = rawText(fn)
print(rt)

for line in rt:
    print ("iterated got: " , line)

print(rt)

输出:

t.txt                                # str before reading data
iterated got:  a,b,c                 # iterating over stuff
iterated got:  1,2,3
iterated got:  4,5,6
t.txt : a,b,c    1,2,3    4,5,6      # str after reading data

如果你的数据文件更大,你可能不想在你的类中存储所有的行,你应该修改它以某种方式从文件对象中产生。

更多信息见How to implement __iter__(self) for a container object (Python)

【讨论】:

    猜你喜欢
    • 2019-05-19
    • 2017-02-10
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 2021-12-05
    • 2011-05-06
    相关资源
    最近更新 更多