Comment imprimer des objets de classe en utilisant print ()?

j'apprends les ficelles en Python. Lorsque j'essaie d'imprimer un objet de la classe Foobar en utilisant la fonction print() , j'obtiens une sortie comme celle-ci:

<__main__.Foobar instance at 0x7ff2a18c>

y a-t-il un moyen de définir le comportement d'impression (ou la string representation ) d'une classe et ses objets ? Par exemple, lorsque j' appel print() sur un objet de classe, je voudrais imprimer ses membres de données dans un certain format. Comment réaliser cela en Python?

si vous êtes familier avec les classes C++, vous pouvez obtenir ce qui précède pour la norme ostream en ajoutant une méthode friend ostream& operator << (ostream&, const Foobar&) pour la classe.

376
demandé sur Aran-Fey 2009-10-08 06:35:30

10 réponses

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

la méthode __str__ est ce qui se passe lorsque vous l'imprimez, et la méthode __repr__ est ce qui se passe lorsque vous utilisez la fonction repr() (ou lorsque vous la regardez avec l'invite interactive). Si ce n'est pas la méthode la plus Pythonic , Je m'excuse, parce que j'apprends encore trop - mais cela fonctionne.

si aucune méthode __str__ n'est donnée, Python affichera le résultat de __repr__ plutôt. Si vous définissez __str__ mais pas __repr__ , Python utilisera ce que vous voyez ci-dessus comme le __repr__ , mais utilisera tout de même __str__ pour l'impression.

430
répondu Chris Lutz 2018-02-05 16:56:06

comme Chris Lutz a mentionné , cela est défini par la méthode __repr__ dans votre classe.

de la documentation de repr() :

pour de nombreux types, Cette fonction fait une tentative de retourner une chaîne qui donnerait un objet avec la même valeur quand passé à eval() , sinon la représentation est une chaîne enfermée dans des crochets d'angle qui contient le nom du type de l'objet avec de l'information supplémentaire, souvent, y compris le nom et l'adresse de l'objet. Une classe peut contrôler ce que cette fonction renvoie pour ses instances en définissant une méthode __repr__() .

compte tenu de l'essai de classe suivant:

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)

.. il agira de la manière suivante dans le 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

si la méthode __str__ n'est pas définie, print(t) (ou print(str(t)) ) utilisera le résultat de __repr__ à la place de

si aucune méthode __repr__ n'est définie, alors la valeur par défaut est utilisée, ce qui est à peu près équivalent..

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

une manière générique qui peut être appliquée à n'importe quelle classe sans formatage spécifique pourrait être faite comme suit:

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

et puis,

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

produit

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

juste pour ajouter mes deux cents à la réponse de @dbr, voici un exemple de la façon de mettre en œuvre cette phrase à partir de la documentation officielle qu'il a cité:

" [...] pour retourner une chaîne qui donnerait un objet avec la même valeur lorsqu'elle serait passée à eval(), [...] "

compte tenu de la définition de cette 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)

maintenant, il est facile de sérialiser l'instance 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

donc, en lançant le dernier morceau de code, nous obtiendrons:

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

, Mais, comme je l'ai dit dans mon dernier commentaire: plus d'info est juste ici !

12
répondu Antonio Alvarado Hernández 2017-05-23 12:26:25

, Vous devez utiliser __repr__ . C'est une fonction standard comme __init__ . Par exemple:

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
répondu flow_chart 2015-11-04 21:40:05

Pour Python 3:

si le format spécifique n'est pas important (par exemple pour le débogage) il suffit d'hériter de la classe imprimable ci-dessous. Pas besoin d'écrire du code pour chaque objet.

Inspiré par ce réponse

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
répondu PeterM 2017-05-23 11:47:21

une version plus jolie de la réponse 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)

produit une belle liste visuelle des noms et des valeurs.

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

une version encore plus fantaisiste (merci Ruud) trie les articles:

def __str__(self):
    return  str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))
4
répondu MikeyB 2018-03-15 14:30:20

Il y a déjà beaucoup de réponses dans ce fil, mais aucun d'eux en particulier m'a aidé, j'ai du travail moi-même, donc j'espère que celui-ci est un peu plus instructif.

vous devez juste vous assurer que vous avez des parenthèses à la fin de votre classe, E. g:

print(class())

voici un exemple de code d'un projet sur lequel je travaillais:

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

pour imprimer ma classe D'hydrogène, j'ai utilisé ce qui suit:

print(Hydrogen())

s'il vous plaît noter, cela ne fonctionnera pas sans les parenthèses à la fin de L'hydrogène. Ils sont nécessaires.

J'espère que cela vous aidera, faites-moi savoir si vous avez d'autres questions.

1
répondu Stumpy 2015-08-04 04:52:21

utilisez simplement "__ str _ _ " méthode spéciale dans votre classe. Pour ex.

class Adiprogrammer:

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

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

yash = Adiprogrammer ("Aaditya")

print(Yash)

1
répondu Yash Tile 2017-11-11 07:35:15

rien de tout cela ne m'aide vraiment. Je ne veux pas changer la définition de mon objet d'origine juste pour avoir l'impression. IOW: Je ne veux pas utiliser l'héritage ou même mettre ces str fonctions dans ma classe. Ça voudrait dire que je devrais changer tous les cours que je veux déboguer. Au lieu de ça, je préférerais avoir un cours et imprimer tout le contenu du cours. IOW: avoir quelque chose comme

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

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

ceci imprimerait quelque chose comme:

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

Agréable et simple à l'usage et une idée de l'endroit où je n'ai pas à changer les objets d'origine définitions. Si j'ai créer une petite fonction qui déconstruit l'objet, je serais OK avec ça. Puisque je peux simplement appeler la fonction qui sait comment le faire. Je peux l'utiliser en ligne sans changer la définition originale des classes.

-2
répondu Keith 2018-06-24 04:04:27