6 Stimmen

Wie liefere ich eine informelle Zeichenfolgenrepräsentation einer Python-Klasse (nicht Instanz)?

Ich verstehe, wie ich eine informelle Darstellung einer Instanz des Objekts bereitstellen kann, aber ich interessiere mich dafür, eine informelle Zeichenfolgendarstellung des Klassennamens bereitzustellen.

Also möchte ich speziell überschreiben, was zurückgegeben wird, wenn ich die Klasse drucke (__main__.SomeClass).

>>> class SomeClass:
...   def __str__(self):
...     return 'Ich bin eine SomeClass-Instanz.'
... 
>>> SomeClass

>>> print SomeClass
__main__.SomeClass
>>> 
>>> x = SomeClass()
>>> x
<__main__.SomeClass instance at 0x2ba2f0ff3f38>
>>> print x
Ich bin eine SomeClass-Instanz.

8voto

Jürgen Strobel Punkte 2120

Ihr Problem nennt sich Meta-Klassenverwirrung. Bei Klasse A, wenn A.__str__(self) ein Template für Methoden von Instanzen von A ist, wie kann ich eine Methode __str__() für A selbst bereitstellen? Meta-Klassen schaffen Abhilfe.

Die folgenden Links erklären dies besser als ich es hier könnte.

http://gnosis.cx/publish/programming/metaclass_1.html

http://gnosis.cx/publish/programming/metaclass_2.html

Ein kurzes Beispiel hier:

class AMeta(type):
    def __str__(self):
        return "Ich bin die wirklich bemerkenswerte Klasse A"

class A(object):
    __metaclass__ = AMeta
    def __str__(self):
        return "Ich bin eine A-Instanz"

print A
Ich bin die wirklich bemerkenswerte Klasse A
print A()
Ich bin eine A-Instanz

Übrigens können Sie das Gleiche für __repr__ tun.

3voto

Sie müssten die Methode __str__ der Metaklasse überschreiben. Ich weiß nicht wirklich, warum Sie das tun möchten, aber hier ist es trotzdem.

>>> class InformalType(type):
...     def __str__(self):
...             return self.__name__
... 
>>> class MyFoo(object):
...     __metaclass__ = InformalType
...     pass
... 
>>> MyFoo

>>> print MyFoo
MyFoo
>>> foo = MyFoo()
>>> foo
<__main__.MyFoo object at 0x7fdf9581f910>
>>> print foo
<__main__.MyFoo object at 0x7fdf9581f910>
>>>

2voto

agf Punkte 159286

Um die String-Repräsentation der Klasse zu ändern:

class MC(type):
    def __repr__(cls):
        return 'Ich bin ein Test'

class Test:
    __metaclass__ = MC
   pass

print Test

funktioniert einwandfrei.

Wenn repr(Test) aufgerufen wird, wenn Sie __str__ definieren, wird Ihre angepasste Nachricht nicht verwendet.

Wenn Sie jedoch __repr__ wie oben definiert haben und str(Test) aufgerufen wird, wird Ihre angepasste Nachricht verwendet, da __repr__ die Standardsicherung ist und __str__ in type nicht definiert ist.

Wenn Sie nur den Namen ändern möchten:

def renamer(name):
    def wrapper(func):
        func.__name__ = name
        return func
    return wrapper

@renamer('Nicht Test')
class Test: pass
print Test.__name__

Test.__name__ = 'Erneut Test'
print Test.__name__    

wird beide funktionieren, um den Namen der Klasse zu ändern.

1voto

OneOfOne Punkte 88023

Überschreiben Sie stattdessen __repr__.

>>> class SomeClass(object):
...   def __repr__(self):
...     return 'Ich bin eine Instanz von SomeClass.'

1voto

Skurmedel Punkte 20549

Sie können dies mit Metaklassen erreichen.

Beobachten:

>>> class MyMeta(type):
...     def __init__(cls, name, bases, dct):
...             super(MyMeta, cls).__init__(name, bases, dct)
...
...     def __repr__(self):
...             return "MyMeta ist Cool: " + self.__name__
...
>>> class FooType(metaclass=MyMeta):
...     pass
...
>>> FooType
MyMeta ist Cool: FooType

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X