【问题标题】:How do I take a list and parse into a list of objects in a class? (Python)如何获取列表并解析为类中的对象列表? (Python)
【发布时间】:2021-08-11 19:05:43
【问题描述】:

我有一个包含多个对象的类。我应该获取一个文本文件,打开它并将其解析为对象列表,然后返回 Entry 对象列表

我很难理解如何将我从文件中创建的列表转换为对象列表。

class Entry:

    def __init__(self, account_num, name, balance, phone, city):
        self.account_num = account_num
        self.name = name
        self.balance = balance
        self.phone = phone
        self.city = city

def read_file(file_given):
    open_file = open(file_given)
    entry_obj = []
    for line in open_file:
        word = line.split()
        entry_obj.append(word)
    open_file.close()
    return entry_obj

我正在阅读的文本文件包含:

100  Alan   Jones   348.17  8053564820      SLO
700  Suzy   Green   -14.22  8052586912      SLO

【问题讨论】:

  • 文件的输入格式是什么?
  • 能否在帖子中包含文件内容。
  • 看起来entry_obj.append(word) 可能需要是entry_obj.append(Entry(*line.split()))
  • 你正在准备的这个文件中的一行是什么样子的,你能给我们举个例子吗?
  • 你知道如何实例化Entry 对象吗?我建议阅读 python 文档:docs.python.org/3/tutorial/classes.html#class-objects。一旦你可以实例化一个对象,你只需要附加这个对象。

标签: python list file class


【解决方案1】:

也许这样的事情应该可行:

def map_to_entry(line):
    attribute_list = line.split()
    account_num = attribute_list[0]
    name = "{} {}".format(attribute_list[1], attribute_list[2])
    balance = attribute_list[3]
    phone = attribute_list[4]
    city = attribute_list[5]
    
    return Entry(account_num, name, balance, phone, city)

def read_file(file_given):
    open_file = open(file_given)
    entry_obj = []
    for line in open_file:
        entry_obj.append(map_to_entry(line))
    open_file.close()
    return entry_obj

【讨论】:

  • 我会犹豫以这种方式排列参数列表,主要是因为它的可读性和可识别性,并且在将来参数的某些方面发生变化时也可以避免头痛。 (比如一列被删除,或者它们被重新排列)
【解决方案2】:

它可以像使用一样简单

objList = [Entry(*li) for li in data]

但遗憾的是,由于某种原因,你们的名字被这样分开了。 Alan Jones 它会创建一个类似

的列表
[['100', 'Alan', 'Jones', '348.17', '8053564820', 'SLO'], ['700', 'Suzy', 'Green', '-14.22', '8052586912', 'SLO']]

因此我们会得到错误,TypeError: __init__() takes 6 positional arguments but 7 were given。 所以我们必须加入这些元素。

new = []
for l in read_file():
    l[1:2] = [' '.join(l[1:3])]
    l.pop(2)
    new.append(l)
objList = [Entry(*li) for li in new]

objList 的样子。

[<__main__.Entry object at 0x7fe78db6a970>, <__main__.Entry object at 0x7fe78db6acd0>]

【讨论】:

    【解决方案3】:

    您已经定义了您的类,但是为了“实例化”(创建一个实例)类对象,现在您必须调用该类。 (在下面的示例中看到为Entry(),其中() 让我们知道我们正在调用/调用该事物)

    您肯定希望在 init() 方法中保留您的参数,就像您拥有它们一样。保持内容简洁和易于阅读是很好的。 *edit - 我将名称 args 分别更改为 _first 和 _last。原因如下。

    请注意,在下面的示例中,循环变量 line 是一组完整的条目数据。因此,通过在其前面使用星号,Python 将查找一个列表(或者实际上是任何可迭代的),它会自动将每个列表元素作为其自己的 arg 发送给函数调用。

    例如如果 line == 'a b c',则 Entry(*line.split()) 等价于 Entry('a', 'b', 'c')

    class Entry:
        def __init__(self, account_num, name_first, name_last, balance, phone, city):
            self.account_num = account_num
            self.name = name_first + ' ' + name_last
            self.balance = balance
            self.phone = phone
            self.city = city
    
    def read_file(file_given):
        open_file = open(file_given)
        lines = open_file.readlines()
        entry_obj = []
        for line in lines:
            entry_obj.append(Entry(*line.split()))
        open_file.close()
        return entry_obj
    

    **edit - 当然,这假设我们知道接收到的数据列的顺序。有很多更强大的方法可以让这段代码面向未来,但我离题了。

    【讨论】:

    • 这可能不适用于将名称格式化为名字和姓氏的方式,对吧?
    【解决方案4】:

    您可以在迭代期间解压缩所有元素。如果您的姓名始终假定为 First Name 和 Last Name,您可以在创建 Entry 对象之前将它们连接起来。下面的例子非常易读:

    entries = []
    for account_num, first_name, last_name, balance, phone, city in read_file('data.txt'):
      name = first_name + " " + last_name
      entries.append(Entry(account_num, name, balance, phone, city))
    

    如果您对此感兴趣,也可以使用单线:

    entries = [Entry(account_num, first_name + " " + last_name, balance, phone, city) for account_num, first_name, last_name, balance, phone, city in read_file('ok.txt')]
    

    在 python 中解包意味着获取一个您事先知道的大小的可迭代对象,并将每个元素解包到不同的变量中。比如:

    a, b, c = ['a', 'b', 'c']
    

    同样的想法可以应用于 for 循环中的元素,该元素本身是另一个可迭代(具有固定大小)的元素,就像文件中的每一行一样。这允许您将列表转换为命名变量,这些变量通常更易于阅读。

    如果你最初的问题是修改read_file函数,你可以使用类似的思路,在迭代文件时解压:

    def read_file(file_given):
        open_file = open(file_given)
        entry_obj = []
        for line in open_file:
            account_num, first_name, last_name, balance, phone, city = line.split()
            name = first_name + " " + last_name
            entry_obj.append(Entry(account_num, name, balance, phone, city))
        open_file.close()
        return entry_obj
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-14
      • 2020-03-15
      • 2020-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      相关资源
      最近更新 更多