首页 文章

如何使用print()打印类的对象?

提问于
浏览
390

我正在学习Python中的绳索 . 当我尝试使用 print() 函数打印类 Foobar 的对象时,我得到如下输出:

<__main__.Foobar instance at 0x7ff2a18c>

有没有办法可以设置类及其对象的打印行为(或字符串表示)?例如,当我在类对象上调用 print() 时,我想以某种格式打印其数据成员 . 如何在Python中实现这一点?

如果您熟悉C类,则可以通过为类添加 friend ostream& operator << (ostream&, const Foobar&) 方法来实现上述标准 ostream .

11 回答

  • 12
    >>> class Test:
    ...     def __repr__(self):
    ...         return "Test()"
    ...     def __str__(self):
    ...         return "member of Test"
    ... 
    >>> t = Test()
    >>> t
    Test()
    >>> print(t)
    member of Test
    

    __str__ 方法是打印时发生的方法, __repr__ 方法是使用repr()函数时(或者当您使用交互式提示查看它时) . 如果这不是最恐怖的方法,我道歉,因为我还在学习 - 但它有效 .

    如果没有给出 __str__ 方法,Python将打印 __repr__ 的结果 . 如果您定义 __str__ 但不是 __repr__ ,Python将使用您在上面看到的 __repr__ ,但仍然使用 __str__ 进行打印 .

  • 7

    As Chris Lutz mentioned,这是由您 class 中的 __repr__ 方法定义的 .

    repr()的文档:

    对于许多类型,此函数尝试返回一个字符串,该字符串在传递给eval()时会产生具有相同值的对象,否则该表示形式是一个括在尖括号中的字符串,其中包含对象类型的名称以及通常包括对象的名称和地址的其他信息 . 类可以通过定义__repr __()方法来控制此函数为其实例返回的内容 .

    鉴于以下课程测试:

    class Test:
        def __init__(self, a, b):
            self.a = a
            self.b = b
    
        def __repr__(self):
            return "<Test a:%s b:%s>" % (self.a, self.b)
    
        def __str__(self):
            return "From str method of Test: a is %s, b is %s" % (self.a, self.b)
    

    ..it将在Python shell中采用以下方式:

    >>> t = Test(123, 456)
    >>> t
    <Test a:123 b:456>
    >>> print repr(t)
    <Test a:123 b:456>
    >>> print(t)
    From str method of Test: a is 123, b is 456
    >>> print(str(t))
    From str method of Test: a is 123, b is 456
    

    如果没有定义 __str__ 方法, print(t) (或 print(str(t)) )将使用 __repr__ 的结果

    如果没有定义 __repr__ 方法,则使用默认值,这几乎相当于..

    def __repr__(self):
        return "<%s instance at %s>" % (self.__class__.__name__, id(self))
    
  • 1

    可以应用于没有特定格式的任何类的通用方法可以按如下方式完成:

    class Element:
        def __init__(self, name, symbol, number):
            self.name = name
            self.symbol = symbol
            self.number = number
    
        def __str__(self):
            return str(self.__class__) + ": " + str(self.__dict__)
    

    然后,

    elem = Element('my_name', 'some_symbol', 3)
    print(elem)
    

    产生

    __main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}
    
  • 448

    只是将我的两分钱加到@dbr的答案中,以下是如何从他引用的官方文档中实现这句话的一个例子:

    “[...]返回一个字符串,当传递给eval(),[...]时会产生一个具有相同值的对象

    鉴于此类定义:

    class Test(object):
        def __init__(self, a, b):
            self._a = a
            self._b = b
    
        def __str__(self):
            return "An instance of class Test with state: a=%s b=%s" % (self._a, self._b)
    
        def __repr__(self):
            return 'Test("%s","%s")' % (self._a, self._b)
    

    现在,很容易序列化 Test 类的实例:

    x = Test('hello', 'world')
    print 'Human readable: ', str(x)
    print 'Object representation: ', repr(x)
    print
    
    y = eval(repr(x))
    print 'Human readable: ', str(y)
    print 'Object representation: ', repr(y)
    print
    

    所以,运行最后一段代码,我们将得到:

    Human readable:  An instance of class Test with state: a=hello b=world
    Object representation:  Test("hello","world")
    
    Human readable:  An instance of class Test with state: a=hello b=world
    Object representation:  Test("hello","world")
    

    但是,正如我在上一篇评论中所说:更多信息只是here

  • 104

    你需要使用 __repr__ . 这是一个像 __init__ 这样的标准函数 . 例如:

    class Foobar():
        """This will create Foobar type object."""
    
        def __init__(self):
            print "Foobar object is created."
    
        def __repr__(self):
            return "Type what do you want to see here."
    
    a = Foobar()
    
    print a
    
  • 24

    对于Python 3:

    如果特定格式不重要(例如,用于调试),只需继承下面的Printable类 . 无需为每个对象编写代码 .

    灵感来自this答案

    class Printable:
        def __repr__(self):
            from pprint import pformat
            return "<" + type(self).__name__ + "> " + pformat(vars(self), indent=4, width=1)
    
    # Example Usage
    class MyClass(Printable):
        pass
    
    my_obj = MyClass()
    my_obj.msg = "Hello"
    my_obj.number = "46"
    print(my_obj)
    
  • 1

    @ user394430的一个更漂亮的响应版本

    class Element:
        def __init__(self, name, symbol, number):
            self.name = name
            self.symbol = symbol
            self.number = number
    
        def __str__(self):
            return  str(self.__class__) + '\n'+ '\n'.join(('{} = {}'.format(item, self.__dict__[item]) for item in self.__dict__))
    
    elem = Element('my_name', 'some_symbol', 3)
    print(elem)
    

    生成视觉上很好的名称和值列表 .

    <class '__main__.Element'>
    name = my_name
    symbol = some_symbol
    number = 3
    

    一个更加漂亮的版本(感谢Ruud)对这些项目进行排序:

    def __str__(self):
        return  str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))
    
  • -2

    在这个帖子中已经有很多答案,但是没有一个特别对我有帮助,我必须自己解决,所以我希望这个有一点信息量 .

    你必须确保在课程结束时有括号,例如:

    print(class())
    

    这是我正在处理的项目的代码示例:

    class Element:
        def __init__(self, name, symbol, number):
            self.name = name
            self.symbol = symbol
            self.number = number
        def __str__(self):
            return "{}: {}\nAtomic Number: {}\n".format(self.name, self.symbol, self.number
    
    class Hydrogen(Element):
        def __init__(self):
            super().__init__(name = "Hydrogen", symbol = "H", number = "1")
    

    要打印我的Hydrogen类,我使用了以下内容:

    print(Hydrogen())
    

    请注意,如果没有Hydrogen末端的括号,这将无效 . 他们是必要的 .

    希望这有帮助,如果您有任何疑问,请告诉我 .

  • 1

    只需在您的 class 中使用 "str" 特殊方法 . 对于前者

    类Adiprogrammer:

    def __init__(self, name):
        self.company_name = name
    
    def __str__(self):
        return "I am the Founder of Adiprogrammer!"
    

    yash = Adiprogrammer(“Aaditya”)

    打印(佳日)

  • 7

    如果您遇到类似@Keith的情况,可以尝试:

    print a.__dict__
    

    这违背了我认为好的风格,但如果你只是试图调试那么它应该做你想要的 .

  • 12

    这些都没有真正帮助我 . 我不希望使用继承,甚至将这些 str 函数放在我的 class 中 . 这意味着我宁愿拥有一个Class并打印出整个类的内容 . IOW:有类似的东西

    class Address( ):
      __init__( self )
         self.mName = 'Joe'
         self.mAddress = '123 Easy Street'
    
    a = Address()
    print a
    or
    print printClass( a )
    

    这将打印如下:

    Class Address contains:
       mName = 'Joe'
       mAddress = '123 Easy Street'
    

    关于用法的简单和简单,以及我不必更改原始对象定义的想法 . 如果我必须创建一个解构对象的小函数,我就可以了 . 因为我可以简单地调用知道如何操作的函数 . 我可以在不改变原始类定义的情况下使用它 .

相关问题