Como imprimir os objectos da classe usando a impressão()?

Estou a aprender as cordas em Python. Quando tento imprimir um objecto de classe Foobar utilizar a print() função, eu recebo uma saída como esta:

<__main__.Foobar instance at 0x7ff2a18c>

Existe uma forma de definir o comportamento de Impressão (ou a representação de caracteres ) de uma classe e dos seusobjectos ? Por exemplo, quando eu chamo print() em um objeto de classe, eu gostaria de imprimir seus membros de dados em um determinado formato. Como conseguir isso em Python?

Se você está familiarizado com classes C++, O acima pode ser alcançado para o padrão ostream adicionando um friend ostream& operator << (ostream&, const Foobar&) método para a classe.

Author: Aran-Fey, 2009-10-08

10 answers

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

O Método __str__ é o que acontece quando se imprime, e o método __repr__ é o que acontece quando se usa o repr() função (ou quando você olhar para ele com o prompt interativo). Se este não é o método mais Pythonic , peço desculpa, porque ainda estou a aprender também - mas funciona.

Se não for indicado o método __str__, o Python irá imprimir o resultado de __repr__ em vez disso. Se você definir __str__ mas não __repr__, o Python irá usar o que você vê acima como __repr__, mas ainda usar __str__ para imprimir.

 430
Author: Chris Lutz, 2018-02-05 16:56:06

Como Chris Lutz mencionou , isto é definido pelo método __repr__ na sua classe.

Da documentação de repr():

Para muitos tipos, esta função faz uma tentativa para retornar uma seqüência de caracteres que produziria um objeto com o mesmo valor quando é passado para eval(), caso contrário, a representação é uma seqüência de caracteres entre parênteses em ângulo que contém o nome do tipo de objeto, juntamente com informações adicionais, incluindo frequentemente o nome de e o endereço do objecto. Uma classe pode controlar o que esta função retorna para suas instâncias, definindo um método __repr__().

Dado o seguinte teste de classe:

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)
Ele agirá da seguinte forma na shell Python:
>>> 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

Se o método de __str__ não estiver definido, print(t) (ou print(str(t))) irá usar o resultado de __repr__ em vez de

Se o método __repr__ não for definido, então o valor por omissão é usado, o que é praticamente equivalente a..

def __repr__(self):
    return "<%s instance at %s>" % (self.__class__.__name__, id(self))
 101
Author: dbr, 2018-02-05 19:17:57

Uma forma genérica que pode ser aplicada a qualquer classe sem formatação específica pode ser feita da seguinte forma:

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__)

E depois,

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

Produz

__main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}
 18
Author: user394430, 2015-09-17 16:35:05

Só para adicionar os meus dois cêntimos à resposta de @dbr, segue - se um exemplo de como implementar esta frase a partir da documentação oficial que ele citou:

"[...] to return a string that would yield an object with the same value when passed to eval (), [...]"

Dada esta definição de classe:

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)

Agora, é fácil serializar a instância de Test classe:

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
Então, ao executar o último pedaço de código, vamos conseguir ...
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")
Mas, como eu disse na minha último comentário: mais informações são apenas aqui !
 12
Author: Antonio Alvarado Hernández, 2017-05-23 12:26:25

Tem de utilizar __repr__. Esta é uma função padrão como __init__. Por exemplo:

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
 11
Author: flow_chart, 2015-11-04 21:40:05

Para O Python 3:

Se o formato específico não for importante (por exemplo, para depuração) apenas herdará da classe de Impressão abaixo. Não há necessidade de escrever código para cada objeto.

Inspirado por esta resposta

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)
 7
Author: PeterM, 2017-05-23 11:47:21
Uma versão mais bonita da resposta de @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)

Produz uma lista visualmente agradável dos nomes e valores.

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

Uma versão ainda mais elegante (thanks Ruud) ordena os itens:

def __str__(self):
    return  str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))
 4
Author: MikeyB, 2018-03-15 14:30:20
Já há muitas respostas neste tópico, mas nenhuma delas me ajudou particularmente, tive de ser eu a resolvê-las, por isso espero que esta seja um pouco mais informativa.

Só tens de ter a certeza que tens parêntesis no final da tua aula, p. ex.:

print(class())
Aqui está um exemplo de código de um projeto em que eu estava trabalhando.
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")

Para imprimir a minha classe de hidrogénio, usei o seguinte:

print(Hydrogen())

Por favor, note, isto não vai funcionar sem os parêntesis no fim do hidrogénio. São necessárias.

Espero que isto ajude, avisa-me se tiveres mais perguntas.
 1
Author: Stumpy, 2015-08-04 04:52:21

Basta usar "__str__" método especial dentro da sua classe. Para ex.

Programa De Classe:

def __init__(self, name):
    self.company_name = name

def __str__(self):
    return "I am the Founder of Adiprogrammer!"

Yash = Adiprogramador ("Aaditya")

Imprimir (yash)

 1
Author: Yash Tile, 2017-11-11 07:35:15
Nada disto me ajuda. Não quero mudar a definição do meu objecto original só para obter a impressão. IOW: eu não quero usar herança ou mesmo colocar estas funções str na minha classe. Isso significaria que teria de mudar todas as aulas que quero depurar. Em vez disso, prefiro ter uma aula e imprimir todo o conteúdo da turma. Come qualquer coisa do género.
class Address( ):
  __init__( self )
     self.mName = 'Joe'
     self.mAddress = '123 Easy Street'

a = Address()
print a
or
print printClass( a )

Isto imprimiria algo como:

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

Agradável e simples sobre o uso e uma ideia onde não tenho de mudar as definições dos objectos originais. Se tiver de criar uma pequena função que desconstrua o objecto, não me importo. Desde que eu posso simplesmente chamar a função que sabe como fazê-lo. Posso usá-lo em linha sem alterar a definição original das classes.

 -2
Author: Keith, 2018-06-24 04:04:27