2011-08-18 7 views
6

Rozumiem, w jaki sposób mogę zapewnić nieformalną reprezentację instancji obiektu obiektu, ale jestem zainteresowany dostarczeniem nieformalnej reprezentacji ciągów klasy Nazwa.Jak zapewnić nieformalną reprezentację ciągów klasy Pythona (bez instancji)

Tak więc, chcę nadpisać to, co jest zwracane, gdy drukuję klasę (__main __. SomeClass).

>>> class SomeClass: 
... def __str__(self): 
...  return 'I am a SomeClass instance.' 
... 
>>> SomeClass 
<class __main__.SomeClass at 0x2ba2f0fd3b30> 
>>> print SomeClass 
__main__.SomeClass 
>>> 
>>> x = SomeClass() 
>>> x 
<__main__.SomeClass instance at 0x2ba2f0ff3f38> 
>>> print x 
I am a SomeClass instance. 

Odpowiedz

8

Twój problem nazywa się zamieszaniem meta class. W klasie A, jeśli A.__str__(self) jest szablonem metod instancji klasy A, w jaki sposób mogę zapewnić metodę dla samego siebie? Meta klasy na ratunek.

Poniższe linki wyjaśniają to lepiej niż ja tutaj.

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

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

Krótki przykład tutaj:

class AMeta(type): 
    def __str__(self): 
     return "I am the truly remarkable class A" 

class A(object): 
    __metaclass__ = AMeta 
    def __str__(self): 
     return "I am an A instance" 

print A 
I am the truly remarkable class A 
print A() 
I am an A instance 

Btw można zrobić to samo dla __repr__.

+0

Zmieniono, dodano przykład. –

+0

Doskonała dokumentacja i przykłady, dzięki! – adam

+0

Myślę, że chodziło o 'def __str __ (self):' in 'class A' zamiast' def str (self): ' –

1

zastępuje __repr__ zamiast tego.

>>> class SomeClass(object): 
... def __repr__(self): 
...  return 'I am a SomeClass instance.' 
+0

Nie, to zastępuje reprezentację instancji. –

+0

'__repr__' jest również dla instancji. nie robi tego, co mówi, próbowałem dekorować '__repr__' za pomocą @ classmethod, ale nie działało :). – utdemir

+0

Twój kod nadal nie działa, ponieważ aby być przydatnym do repr (SomeClass), twój 'SomeClass .__ repr__' nie może mieć własnego argumentu. –

2

Aby zmienić reprezentację klasy string:

class MC(type): 
    def __repr__(cls): 
     return 'I am Test' 

class Test: 
    __metaclass__ = MC 
    pass 

print Test 

działa dobrze.

Jeśli zostanie zdefiniowane repr(Test) podczas definiowania __str__, to nie będzie korzystać z wiadomości o gotowości.

Jeśli jednak określić __repr__ jak ja, i str(Test) nazywa, to będzie używać custimized wiadomość, ponieważ __repr__ jest awaryjna i __str__ nie jest zdefiniowane w type.

Jeśli wszystko, co chcesz zrobić, to zmienić jej nazwę:

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

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

Test.__name__ = 'Test Again' 
print Test.__name__  

będą zarówno prace, aby zmienić nazwę klasy.

+0

Chce zmienić sposób drukowania klasy (jako str), a nie jej nazwę. –

+0

Spójrz na mój pierwszy przykład kodu, robi dokładnie to. Drugi przykład to ten, który zmienia nazwę. W rzeczywistości moja odpowiedź miała to przed twoją. – agf

1

Można to osiągnąć za pomocą metaclasses.

przestrzegać:

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

trzeba by zastąpić metodę z metaklasą__str__. Naprawdę nie wiem, dlaczego chciałbyś to zrobić, ale tutaj tak jest.

>>> class InformalType(type): 
...  def __str__(self): 
...    return self.__name__ 
... 
>>> class MyFoo(object): 
...  __metaclass__ = InformalType 
...  pass 
... 
>>> MyFoo 
<class '__main__.MyFoo'> 
>>> print MyFoo 
MyFoo 
>>> foo = MyFoo() 
>>> foo 
<__main__.MyFoo object at 0x7fdf9581f910> 
>>> print foo 
<__main__.MyFoo object at 0x7fdf9581f910> 
>>> 
+0

+1 O wiele czystsze niż moja wersja. – Skurmedel

Powiązane problemy