14

我有一个 Python 脚本,它处理一个包含报告使用信息的 .txt 文件。我想找到一种使用 pprint 的 pprint(vars(object)) 函数干净地打印对象属性的方法。

该脚本读取文件并创建 Report 类的实例。这是课程。

class Report(object):
    def __init__(self, line, headers):
        self.date_added=get_column_by_header(line,headers,"Date Added")
        self.user=get_column_by_header(line,headers,"Login ID")
        self.report=get_column_by_header(line,headers,"Search/Report Description")
        self.price=get_column_by_header(line,headers,"Price")
        self.retail_price=get_column_by_header(line,headers,"Retail Price")

    def __str__(self):
        from pprint import pprint
        return str(pprint(vars(self)))

我希望能够干净地打印报告实例 a-la-pprint。

for i,line in enumerate(open(path+file_1,'r')):
    line=line.strip().split("|")
    if i==0:
        headers=line

    if i==1:
        record=Report(line,headers)
        print record

当我打电话

print record

对于 Report 的单个实例,这就是我在 shell 中得到的。

{'date_added': '1/3/2012 14:06',
'price': '0',
'report': 'some_report',
'retail_price': '0.25',
'user': 'some_username'}
 None

我的问题有两个。

首先,这是干净地打印对象属性的好/理想方式吗?有没有更好的方法可以使用或不使用 pprint?

二、为什么

None

最后打印到外壳?我很困惑这是从哪里来的。

感谢您的任何提示。

4

5 回答 5

31

丹的解决方案是错误的,而伊斯梅尔的解决方案不完整。

  1. __str__()不叫,__repr__()叫。
  2. __repr__()应该返回一个字符串,就像 pformat 一样。
  3. print 通常只缩进 1 个字符并尝试保存行。如果您想弄清楚结构,请将宽度设置为低,缩进高。

这是一个例子

class S:
    def __repr__(self):
        from pprint import pformat
        return pformat(vars(self), indent=4, width=1)

a = S()
a.b = 'bee'
a.c = {'cats': ['blacky', 'tiger'], 'dogs': ['rex', 'king'] }
a.d = S()
a.d.more_c = a.c

print(a)

这打印

{   'b': 'bee',
    'c': {   'cats': [   'blacky',
                         'tiger'],
             'dogs': [   'rex',
                         'king']},
    'd': {   'more_c': {   'cats': [   'blacky',
                               'tiger'],
                  'dogs': [   'rex',
                              'king']}}}

这并不完美,但可以通过。

于 2014-05-25T03:12:57.927 回答
13

pprint.pprint不返回字符串;它实际上进行打印(默认为标准输出,但您可以指定输出流)。所以当你写的时候print recordrecord.__str__()被调用,调用pprint,返回Nonestr(None)'None',那会被print编辑,这就是你看到 的原因None

你应该pprint.pformat改用。(或者,您可以将StringIO实例传递给pprint.)

于 2012-02-03T21:12:38.993 回答
5

pprint只是另一种形式的印刷品。当您说pprint(vars(self))它将 vars 打印到 stdout 并返回 none 时,因为它是一个 void 函数。因此,当您将其转换为字符串时,它会将None(由 返回pprint)转换为字符串,然后从初始打印语句中打印该字符串。我建议将您的打印更改为pprint或将打印重新定义为打印,如果您将其全部用于打印。

def __str__(self):
    from pprint import pprint
    return str(vars(self))

for i,line in enumerate(open(path+file_1,'r')):
    line = line.strip().split("|")
    if i == 0:
        headers = line
    if i == 1:
        record = Report(line,headers)
        pprint record

一种替代方法是使用格式化输出:

def __str__(self):
    return "date added:   %s\nPrice:        %s\nReport:       %s\nretail price: %s\nuser:         %s" % tuple([str(i) for i in vars(self).values()])

希望这有帮助

于 2012-02-03T21:31:06.470 回答
5

我认为beeprint是你需要的。

只需pip install beeprint将您的代码更改为:

def __str__(self):
    from beeprint import pp
    return pp(self, output=False)
于 2016-09-13T10:24:42.427 回答
3

对于包含其他对象等的漂亮打印对象pprint是不够的。试试基于 Ruby 模块的IPython 的 lib.pretty 。

from IPython.lib.pretty import pprint
pprint(complex_object)
于 2014-04-13T01:20:29.543 回答