3

according to this post, I can enumerate instance variable by accessing str(self.__dict__), but I can't figure out how to do that with class variables.

Here's what I want to AVOID:

# I would like to print out class attributes by overriding `__str__` for that class.
class circle(object):
    radius = 3
    def __str__(self):     # I want to avoid instantiation like this.
        return str(circle.radius)

print(circle())    # I want to avoid instantiation. why can't I just print(circle)?
Sajuuk
  • 2,667
  • 3
  • 22
  • 34
  • Related (or dupe?): https://stackoverflow.com/questions/4932438/how-to-create-a-custom-string-representation-for-a-class-object – Aran-Fey Mar 27 '18 at 09:14
  • @Aran-Fey I believe the answer presented in this question are much more clear than answers there. besides, the question is not exactly the same. – Sajuuk Mar 27 '18 at 12:45

2 Answers2

5

print(circle()) will call the __str__ method on an instance of circle.

class circle:
  def __str__(self):
    pass

as you can see here, you define __str__ on an instance of circle by using def on the parent class. Therefore you can override the __str__ method on the CLASS by using ITS parent.

 class circle(object):
     class __metaclass__(type):
         def __str__(cls):
             return str(cls.__dict__)
     radius = 3

Now, print circle will give you

{'__module__': '__main__', '__metaclass__': <class '__main__.__metaclass__'>, 'radius': 3, '__dict__': <attribute '__dict__' of 'circle' objects>, '__weakref__': <attribute '__weakref__' of 'circle' objects>, '__doc__': None}

EDIT python3 metaclass syntax

class meta(type):
  def __str__(cls):
    return str(cls.__dict__)

class circle(object, metaclass=meta):
  radius = 3
Paul Becotte
  • 9,767
  • 3
  • 34
  • 42
  • Well at first I thought this is exactly what I want, but there's a minor problem: this code only seem to work on Python2, not Python3. – Sajuuk Mar 27 '18 at 06:34
4

You can use the __dict__ member of the class object itself (possibly filtering out keys starting with __).

class circle(object):
    radius = 3

print({k: v for k,v in circle.__dict__.items() if not k.startswith('__')}) # prints {'radius': 3}
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299