2010-03-23 4 views
9

Comment puis-je remplacer une méthode spéciale de classe?Python classe dominante (pas d'exemple) méthodes spéciales

Je veux être en mesure d'appeler la méthode __str__() de la classe sans créer une instance. Exemple:

class Foo: 
    def __str__(self): 
     return 'Bar' 

class StaticFoo: 
    @staticmethod 
    def __str__(): 
     return 'StaticBar' 

class ClassFoo: 
    @classmethod 
    def __str__(cls): 
     return 'ClassBar' 

if __name__ == '__main__': 
    print(Foo) 
    print(Foo()) 
    print(StaticFoo) 
    print(StaticFoo()) 
    print(ClassFoo) 
    print(ClassFoo()) 

produit:

<class '__main__.Foo'> 
Bar 
<class '__main__.StaticFoo'> 
StaticBar 
<class '__main__.ClassFoo'> 
ClassBar 

devrait être:

Bar 
Bar 
StaticBar 
StaticBar 
ClassBar 
ClassBar 

Même si j'utilise le @staticmethod ou @classmethod le __str__ utilise encore la définition Python intégré pour __str__. Cela fonctionne seulement quand c'est Foo().__str__() au lieu de Foo.__str__().

+0

-1: "appeler la méthode' __str __() 'de la classe sans créer une instance". Brise toute compréhension que tout le monde a de ce qu'est un objet. S'il vous plaît ne faites pas cela. Cela fait que le programme viole absolument nos attentes les plus fondamentales. –

+5

Je ne suis pas d'accord. Si vous appelez str (MyClass), il n'y a aucune raison pour que vous vous comportez comme si vous appeliez simplement str (myClassObject). Autrement dit, il n'y a pas d'attentes fondamentales pour commencer. Je soupçonne qu'il veut créer une classe statique et n'a jamais l'intention de créer des instances de celui-ci. –

Répondre

17

La méthode spéciale __str__ définie dans une classe ne fonctionne que pour les instances de cette classe, pour avoir le comportement différent pour les objets de classe, vous devrez le faire dans une métaclasse de cette classe, par exemple. (Python 2,5)

class Meta(type): 
    def __str__(self): 
     return "Klass" 

class A(object): 
    __metaclass__ = Meta 

    def __str__(self): 
     return "instance" 

print A 
print A() 

sortie:

Klass 
instance 
+1

je devais utiliser la nouvelle syntaxe PY3 de classe C (metaclass = M): ... mais ça marche! –

1

Pourquoi voulez-vous abuser du sens de __str__? Cette méthode est réservée à la signification "renvoie une représentation sous forme de chaîne de cette instance".

Si vous voulez une fonction qui renvoie simplement une chaîne statique, il serait préférable d'avoir que comme une fonction distincte non à l'intérieur d'une classe.

Si vous voulez un constructeur qui retourne une nouvelle chaîne, nommez-la quelque chose d'autre, afin qu'elle n'obstrue pas le nom __str__ réservé.

0

Je ne sais pas ce que vous essayez de faire, exactement. Permettez-moi d'ajouter un peu d'information au hasard.

D'abord, ajoutez cette classe:

class FooNew(object): 
def __str__(self): 
    return 'Fubar' 

Imprimer ceci:

if __name__ == '__main__': 
    print "You are calling type for an old style class" 
    print(Foo) 
    print(type.__str__(Foo)) 
    print(Foo()) 
    print("But my Python 2.6 didn't match your output for print(Foo)") 
    print("You are calling object.str() for a new style class") 
    print(FooNew) 
    print(object.__str__(FooNew)) 
    print(FooNew()) 
    print("Why do you want to change this?") 

Pour obtenir:

You are calling type for an old style class 
__main__.Foo 
<class __main__.Foo at 0xb73c9f5c> 
Bar 
But my Python 2.6 didn't match your output for print(Foo) 
You are calling object.str() for a new style class 
<class '__main__.FooNew'> 
<class '__main__.FooNew'> 
Fubar 
Why do you want to change this? 

Êtes-vous absolument sûr que vous ne voulez pas appeler une méthode de classe?

Questions connexes