如何将getattr与dict字符串格式结合使用?

时间:2018-07-02 20:27:29

标签: python string python-2.7 class data-structures

我有一个数据结构类和一个表格式化类,我想在其中格式化文件并将其输出。如果需要更改输出,我想即时创建格式化程序的灵活性。

class Row(object):
    __slots__ = ('date', 'item', 'expiration', 'price')
    def __init__(self, date, item, expiration, price=None):
        self.date = date
        self.item = item
        self.expiration = expiration
        self.price = ""

        if price:
            self.price = price

class Formatter(object):
    def row(self, rowdata):
        for item in rowdata:
            print('<obj date="{date}" item="{item}" exp="{expiration}" price="{price}" />\n').format(**item)


def print_table(objects, colnames, formatter):
    for obj in objects:
        rowdata = [str(getattr(obj, colname)) for colname in colnames]
        formatter.row(rowdata)

我这样称呼:

data = [Row("20180101", "Apples", "20180201", 1.50),
         Row("20180101", "Pears", "20180201", 1.25)]

formatter = Formatter()
print_table(data, ['date','item','expiration','price'], formatter)

我希望看到的是:

<obj date="20180101" item="Apples" exp="20180201" price="1.50" /> <obj date="20180101" item="Pears" exp="20180201" price="1.25" />

我目前遇到以下错误: TypeError: format() argument after ** must be a mapping, not str

有人可以帮忙吗?谢谢

2 个答案:

答案 0 :(得分:2)

固定代码:

class Formatter(object):
    def row(self, rowdata):
        print('<obj date="{date}" item="{item}" exp="{expiration}" price="{price}" />\n'.format(**rowdata))


def print_table(objects, colnames, formatter):
    for obj in objects:
        rowdata = {colname: str(getattr(obj, colname)) for colname in colnames}
        formatter.row(rowdata)

您遇到了3个问题:

  1. 您将行数据视为项目列表,而行数据应为单个 列名和数据之间的映射
  2. 您没有创建映射,仅创建了结果。 {colname: str(getattr(obj, colname)) for colname in colnames}在名称和属性之间创建映射。然后,您可以将其传递给.format(),它将完全起作用。
  3. 您在format()函数上使用了print()。您应该在里面的字符串上使用它。

答案 1 :(得分:0)

**item无效,因为**运算符期望命名变量是字典( mapping ),而您没有提供该变量(item是字符串) 。因此,您需要将item转换为字典,并在format语句中使用所需的正确键/值对。