How do I use getattr in conjunction with dict string formatting?
How do I use getattr in conjunction with dict string formatting?
I have a data structure class and a table formatting class in which I want to format a file and output it. I want the flexibility of creating formatters on the fly if the output needs to be changed.
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)
I'm calling this like so:
data = [Row("20180101", "Apples", "20180201", 1.50),
Row("20180101", "Pears", "20180201", 1.25)]
formatter = Formatter()
print_table(data, ['date','item','expiration','price'], formatter)
What I'm expecting to see is:
<obj date="20180101" item="Apples" exp="20180201" price="1.50" />
<obj date="20180101" item="Pears" exp="20180201" price="1.25" />
<obj date="20180101" item="Apples" exp="20180201" price="1.50" />
<obj date="20180101" item="Pears" exp="20180201" price="1.25" />
I am currently getting the following error:TypeError: format() argument after ** must be a mapping, not str
TypeError: format() argument after ** must be a mapping, not str
Can anyone help with this? Thanks
rowdata
2 Answers
2
Fixed code:
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)
You had 3 problems:
{colname: str(getattr(obj, colname)) for colname in colnames}
.format()
format()
print()
**item
is invalid because the **
operator expects the named variable to be a dictionary (a mapping), and you have not provided that (item is a string). Thus, you need to convert item
into a dictionary with the proper key/value pairs that you want in your format statement.
**item
**
item
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You don't seem to create a dict at any point in this code, yet you're trying to use
rowdata
as if its elements are dicts.– user2357112
Jul 2 at 20:32