Python 对象的 __str__ 方法

22 投票
3 回答
65576 浏览
提问于 2025-04-17 00:08

在尝试了解BeautifulSoup是怎么工作的过程中,我偶然学到了__str__这个方法(我刚接触python)。如果我没有理解错的话,__str__方法是用来定义当你打印这个类的时候,它会以什么样的形式显示出来。例如:

class Foo:
    def __str__(self):
        return "bar"

>>> x = Foo()
>>> print x
bar

对吧?所以如果我理解得没错的话,是否可以重写一个字典列表的__str__方法?我的意思是说,在类Foo里面你有:

class Foo:
   def __init__(self):
      self.l = [{"Susan": ("Boyle", 50, "alive")}, {"Albert": ("Speer", 106, "dead")}]

那么,是否可以得到以下的结果呢?

>>> x = Foo()
>>> print x.l
"Susan Boyle is 50 and alive. Albert Speer is 106 and dead."

编辑

考虑到agf的解决方案,我该如何再次访问这个字典呢?我的意思是,如果我定义了__str__方法,那么显然我还需要定义其他东西来以原样获取字典。请看下面的例子:

class PClass(dict):
    def __str__(self):
        # code to return the result that I want 

class Foo:
    def __init__(self):
        self.l = PClass({"Susan": ["Boyle", ........ })

>>> x = Foo()
>>> print x.l 
# result that works great
>>> y = x.l["Susan"] # this would not work. How can I achieve it? 

3 个回答

0

你可以为你的 Foo 类定义一个 __str__ 方法,这样可以返回你想要的内容:

class Foo():
    def __init__(self):
        self.l = [{"Susan": ("Boyle", 50, "alive")}, {"Albert": ("Speer", 106, "
dead")}]
    def __str__(self):
        ret_str = ""
        for d in self.l:
            for k in d:
                ret_str += "".join([k, " ", d[k][0], " is ", str(d[k][1]), " and
 ", d[k][2], ". "])
        return ret_str

foo = Foo()
print foo

这样会得到:

Susan Boyle 50岁,活着。Albert Speer 106岁,已经去世。

4

另一种选择是重写 __getattribute__ 这个方法,这样你就可以自定义属性是如何被返回的:

class Foo(object):
    def __init__(self):
        self.l = [{"Susan": ("Boyle", 50, "alive")}, {"Albert": ("Speer", 106, "dead")}]

    def __getattribute__(self, name):
        return PrintableList(l)
        attr = super(Foo, self).__getattribute__(name)
        items = sum([x.items() for x in attr], [])
        return ' '.join([' '.join([k, v[0], 'is', str(v[1]), 'and', v[2] + '.']) for k,v in items])

>>> f = Foo()
>>> print f.l
<<< Susan Boyle is 50 and alive. Albert Speer is 106 and dead.
22

你需要创建一个你想要漂亮打印的项目的子类。

from itertools import chain

class PrintableList(list): # for a list of dicts
    def __str__(self):
        return '. '.join(' '.join(str(x) for x in
            chain.from_iterable(zip((item[0], 'is', 'and'), item[1])))
                for item in (item.items()[0] for item in self)) + '.'

class PrintableDict(dict): # for a dict
    def __str__(self):
        return '. '.join(' '.join(str(x) for x in
            chain.from_iterable(zip((item[0], 'is', 'and'), item[1])))
                for item in self.iteritems()) + '.'

class Foo:
   def __init__(self):
      self.d = PrintableDict({"Susan": ("Boyle", 50, "alive"), 
                              "Albert": ("Speer", 106, "dead")})

class Bar:
   def __init__(self):
      self.l = PrintableList([{"Susan": ("Boyle", 50, "alive")}, 
                              {"Albert": ("Speer", 106, "dead")}])

foo = Foo()
print self.d
bar = Bar()
print self.l

撰写回答