J'apprends les ficelles du métier en Python. Lorsque j'essaie d'imprimer un objet de classe Foobar
à l'aide de la fonction print()
, j'obtiens un résultat comme celui-ci:
<__main__.Foobar instance at 0x7ff2a18c>
Est-il possible de définir le comportement d'impression (ou la représentation de chaîne ) d'une classe et de ses objets ? Par exemple, lorsque j'appelle print()
sur un objet de classe, j'aimerais imprimer ses données membres dans un certain format. Comment y parvenir en Python?
Si vous connaissez bien les classes C++, vous pouvez obtenir ce qui précède pour la variable standard ostream
en ajoutant une méthode friend ostream& operator << (ostream&, const Foobar&)
à la classe.
>>> 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__
correspond à ce qui se passe lorsque vous l’imprimez, et la méthode __repr__
à l’utilisation de la fonction repr()
(ou lorsque vous la regardez avec l’invite interactive ). Si ce n'est pas la méthode la plus courante Pythonic , je m'excuse, car j'apprends encore aussi - mais cela fonctionne.
Si aucune méthode __str__
n'est donnée, Python imprimera le résultat de __repr__
à la place. Si vous définissez __str__
mais pas __repr__
, Python utilisera ce que vous voyez ci-dessus comme le __repr__
, mais utilisera toujours __str__
pour l'impression.
Comme Chris Lutz l'a mentionné , ceci est défini par la méthode __repr__
de votre classe.
De la documentation de repr()
:
Pour de nombreux types, cette fonction tente de renvoyer une chaîne qui donnerait un objet avec la même valeur si elle est transmise à
eval()
. Sinon, la représentation est une chaîne entourée de crochets angulaires contenant le nom du type de l'objet avec des informations supplémentaires. informations comprenant souvent le nom et l'adresse de l'objet. Une classe peut contrôler ce que cette fonction retourne pour ses instances en définissant une méthode__repr__()
.
Étant donné le test 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 aucune méthode __str__
n'est définie, print(t)
(ou print(str(t))
) utilisera le résultat de __repr__
à la place.
Si aucune méthode __repr__
n'est définie, alors la méthode par défaut est utilisée, ce qui équivaut à peu près à ..
def __repr__(self):
return "<%s instance at %s>" % (self.__class__.__name__, id(self))
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__)
Puis,
elem = Element('my_name', 'some_symbol', 3)
print(elem)
produit
__main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}
Si vous êtes dans une situation comme @ Keith , vous pouvez essayer:
print a.__dict__
Cela va à l’encontre de ce que j’appellerais un bon style, mais si vous essayez simplement de déboguer, il devrait faire ce que vous voulez.
Pour ajouter mes deux cents à la réponse de @ dbr, voici un exemple d'application de cette phrase à partir de la documentation officielle qu'il a citée:
"[...] pour renvoyer une chaîne qui donnerait un objet avec la même valeur si elle est passée à eval (), [...]"
Étant donné cette définition 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)
Maintenant, il est facile de sérialiser une instance de Test
class:
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 exécutant le dernier morceau de code, nous aurons:
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’informations, c’est juste ici !
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
Pour Python 3:
Si le format spécifique n’est pas important (par exemple, pour le débogage), héritez simplement de la classe Printable ci-dessous. Pas besoin d'écrire du code pour chaque objet.
Inspiré par this answer
class Printable:
def __repr__(self):
from pprint import pformat
return "<" + type(self).__+ "> " + 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)
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 visuellement une belle liste de noms et de valeurs.
<class '__main__.Element'>
name = my_name
symbol = some_symbol
number = 3
Une version encore plus sophistiquée (merci Ruud) trie les éléments:
def __str__(self):
return str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))
Il y a déjà beaucoup de réponses dans ce fil de discussion, mais aucune d’entre elles ne m’a particulièrement aidée; j’ai dû résoudre le problème moi-même. J’espère donc que celui-ci est un peu plus informatif.
Vous devez juste vous assurer que vous avez des parenthèses à la fin de votre cours, par exemple:
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())
Veuillez noter que cela ne fonctionnera pas sans les parenthèses à la fin de l'hydrogène. Ils sont nécessaires.
J'espère que cela aide, faites-moi savoir si vous avez d'autres questions.
utilisez simplement "__ str __" méthode spéciale dans votre classe. Par ex.
classe Adiprogrammer:
def __init__(self, name):
self.company_name = name
def __str__(self):
return "I am the Founder of Adiprogrammer!"
yash = Adiprogrammer ("Aaditya")
imprimer (yash)