How to take the class name inside a python method

Asked

Viewed 482 times

2

I am creating a base class that keeps some common methods for daughter classes in Python3:

import abc

class Bot(abc.ABC):
    def log(self, message):
        bot     = self.__name__
        version = self.__dict__['version']
        print(f"{bot}.{version}|{message}")

class ExampleBot(Bot):
    pass

The intention is that, using inheritance it is possible to take the name of the class in which the method is called without having to replicate code... When I try to do that I get the following mistake:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in log
AttributeError: 'ExampleBot' object has no attribute '__name__'

But if I try to call the property ExampleBot.__name__ direct it returns the expected result. What I need to do to get the name of the class in which the log method was called in this context?

1 answer

6


The class name of an object is available as self.__class__.__name__

Your mistake was that self.__name__ tries to take this attribute in the instance - has this extra step.

Taking advantage of the opportunity, something much more hidden in the documentation, is if you want explicit access to the class where the method was defined (or its name) - to have access to subclass, which called the method, always is self.__class__. If you want the "fixed" class, where the method is defined, just type __class__ - without self or anything. (This is a "magic" variable that is inserted by Python into the scope of the methods only when it is itself or super() are used)

import abc

class Bot(abc.ABC):
    def log(self, message):
        bot     = self.__class__.__name__
        version = self.version
        log_class = __class__.__name__
        print(f"{bot}.{version}|{message}. Log class: {log_class}")

class ExampleBot(Bot):
    pass

(note that in this example, in addition to printing the class where "log" is defined, which is what I wanted to show, I changed the access to the attribute "version" - take the value that is in self.__dict__["nome_do_atributo"] is the normal Python behavior for attributes - and is not required in this case - if you do self.version instead of self.__dict__["version"] this causes normal language mechanisms to be used, and you can have a mixin that changes the "version" attribute dynamically, (using a property, for example.)

  • Thanks boy! That’s exactly what I needed

Browser other questions tagged

You are not signed in. Login or sign up in order to post.