将类别应用于列表中的项目

时间:2019-01-23 02:20:21

标签: python

我想做的是允许将任意数量的属性提供给函数。该函数将处理基于这些属性创建一个类。然后,我有了另一个函数,该函数将处理从文本文件中导入数据,将生成的类应用于每个项目,并将其添加到列表中。以下是我所拥有的。

New price for 'The Hunger Games' book is 7.66
New price for 'Harry Potter and the Sorcerer's Stone' book is 5.26

问题在于我如何尝试将项目添加到列表中。通常,我不会有任何问题,但是我相信创建类的方式会导致我通常的操作方式出现问题。

  

file_to_list中的文件“ file.py”,第17行       var.append(classObject(line))   TypeError: init ()接受1个位置参数,但给出了2个

如何遍历类的每个属性,以便可以为每个属性设置值并将其添加到列表中?

更新: 以下是file.txt外观的示例。

def create_class(attributes):
    class classObject:
        def __init__(self, **attributes):
            for attr in attributes.keys():
                self.__dict__[attr] = attributes[attr]

    return classObject

def file_to_list(file, attributes):
    classObject = create_class(attributes)

    with open(file, "r") as f:
        var = []

        for line in f.readlines():
            var.append(classObject(line))

    return var

data = file_to_list("file.txt", ["propA", "propB"])

2 个答案:

答案 0 :(得分:1)

看来您的班级是错误的。您似乎希望能够做到:

Cls = create_class(["some", "attributes", "go", "here"])

最终得到一个看起来像这样的类对象:

class Cls(object):
    def __init__(self, some, attributes, go, here):
        self.some = some
        self.attributes = attributes
        self.go = go
        self.here = here

但是您实际上正在做的是创建一个带有字典的类,并赋予该字典点语法。

>>> obj = Cls({"different": "attributes", "go": "here"})
>>> obj.different
"attributes"
>>> obj.go
"here"

您可以使用以下方法实现前者:

def create_class(attributes: typing.List[str]):
    class gen_class(object):
        def __init__(self, *args):
            if len(args) != len(attributes):
                # how do you handle the case where the caller specifies fewer or more
                # arguments than the generated class expects? I would throw a...
                raise ValueError(f"Wrong number of arguments (expected {len(attributes)}, got {len(args)}.")
            for attr, value in zip(attributes, args):
                setattr(self, attr, value)

然后,您应该可以使用csv.reader来读取文件并实例化这些类。

import csv

CSV_Cls = create_class(["propA", "propB"])

with open(file) as f:
    reader = csv.reader(f)
    data = [CSV_Cls(*row) for row in reader]

但是,似乎编写自己的代码生成器来制作该类似乎是错误的选择。为什么不使用collections.namedtuple呢?

from collections import namedtuple

CSV_Cls = namedtuple("CSV_Cls", "propA propB")

with open(file) as f:
    reader = csv.reader(f)
    data = [CSV_Cls(*row) for row in reader]

此stdlib代码生成器已经编写,可以正常工作(并经过严格测试),不会偶然引入错误。选择类的唯一原因是,如果您需要将某些行为与数据紧密耦合,或者需要可变的数据结构

答案 1 :(得分:0)

首先,为什么不使用home.php呢?这是默认的元类,即创建类对象的可调用对象。类dict将是第三个参数,这使得通过编程轻松创建。

home.php

(您可能不需要任何基类,但这就是第二个参数的含义。)


第二,您的<li><a href="lesson1.1.php?lessonID=<?php echo $lesson['lessonID'];?>"><?php echo $lesson['lessonName']; ?></a></li> 似乎不接受str,这是您可以从type获得的唯一东西。它仅包含self(隐含)和关键字参数。

您也许可以将type(name, (), attributes) str转换为dict(但这取决于其中的内容),然后将dict用作__init__这样的kwarg,但是这样可能毫无意义。首先在readlines()方法中用星号声明它。