How to provide an informal string representation of a python class (not an instance)

I understand how I can provide an informal representation of an instance of an object, but I'm interested in providing an informal string representation of a class name.

So I want to override what is returned when I print the class (__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. 
+6
source share
5 answers

Your problem is called metaclass confusion. From class A, if A.__str__(self) is a template for instance methods of A, how can I provide the __str__() method for A itself? Meta classes for salvation.

The following links explain this better than I could here.

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

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

A brief example:

 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 you can do the same for __repr__ .

+8
source

you will have to override the metaclass __str__ method. I donโ€™t know why you would like to do this, but here itโ€™s all the same.

 >>> 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> >>> 
+3
source

To change the presentation of a class string:

 class MC(type): def __repr__(cls): return 'I am Test' class Test: __metaclass__ = MC pass print Test 

works great.

If repr(Test) is called when you define __str__ , it will not use your custimized message.

However, if you define __repr__ as I do and str(Test) is called, it will use your custimized message because __repr__ is fallback and __str__ not defined in type .

If all you want to do is change its name:

 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__ 

both will work to change the class name.

+2
source

override __repr__ .

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

You can achieve this with metaclasses.

Note:

 >>> 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 
+1
source

Source: https://habr.com/ru/post/895342/


All Articles