2010-03-23 23 views
9

¿Cómo anulo un método especial de clase?Python que anula la clase (no instancia) métodos especiales

Deseo poder llamar al método __str__() de la clase sin crear una instancia. Ejemplo:

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

produce:

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

debería ser:

Bar 
Bar 
StaticBar 
StaticBar 
ClassBar 
ClassBar 

Incluso si uso el @staticmethod o @classmethod la __str__ sigue utilizando el incorporado en la definición de Python para __str__. Solo funciona cuando es Foo().__str__() en lugar de Foo.__str__().

+0

-1: "llama al método' __str __() 'de la clase sin crear una instancia". Rompe cada entendimiento que alguien tiene de lo que es un objeto. Por favor no hagas esto. Hace que el programa viole absolutamente nuestras expectativas más fundamentales. –

+5

No estoy de acuerdo. Si llama a str (MyClass), entonces no hay ninguna razón por la que espere que se comporte como si acabara de llamar a str (myClassObject). Es decir, no hay expectativas fundamentales para empezar. Sospecho que quiere crear una clase estática y nunca tiene la intención de crear ninguna instancia de la misma. –

Respuesta

17

Método especial __str__ El método especial __str__ definido en una clase funciona solo para las instancias de esa clase, para tener el comportamiento diferente para los objetos de clase, tendrá que hacerlo en una metaclase de esa clase, p. (Pitón 2,5)

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

class A(object): 
    __metaclass__ = Meta 

    def __str__(self): 
     return "instance" 

print A 
print A() 

de salida:

Klass 
instance 
+1

Tuve que usar la nueva sintaxis py3 de clase C (metaclass = M): ... pero funciona! –

1

¿Por qué quiere usted abusar del significado de __str__? Ese método está reservado para el significado "return a string representation of this instance".

Si desea una función que solo devuelve una cadena estática, sería mejor tenerla como una función separada que no esté dentro de una clase.

Si desea un constructor que devuelva una nueva cadena, asígnele un nombre distinto para que no se pegue el nombre __str__ reservado.

0

No estoy seguro de lo que está tratando de hacer, exactamente. Permítanme agregar un poco de información aleatoria.

En primer lugar, añadir esta clase:

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

Imprimir esta vez:

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

Para conseguir esto:

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? 

¿Estás absolutamente seguro de que no quieren llamar ¿un método de clase?

Cuestiones relacionadas