1

Given:

Module A.py
    class utilities:
        
        def __init__(self):
            #Is there a way to get the class that instantiates this constructor ? But here, in the init method?
            
        def utilMethod(self):
            pass


Module B.py
from A import utilities

    class dummy:
    
        utils = utilities()
        
        def dummyMthod(self):
            utils.utilMethod()
            

#Is there a way to get the class that instantiates utilities class constructor ? But in the init method of the class being instanciated?

Rolfsky
  • 63
  • 7
  • The only thing I know of that might give you this information is a stack trace. You should be able to obtain a stack trace for where you currently are, and with it, get information about the caller of the method you are in. Check out the standard `traceback` module. – CryptoFool Feb 15 '21 at 10:56
  • `__init__():` does not take the `self` parameter? – Countour-Integral Feb 15 '21 at 11:00
  • It does now, edited it, mybad – Rolfsky Feb 15 '21 at 11:01
  • How is the second part (`Module B.py`) relevant? You say you only care in the `__init__` method. – Countour-Integral Feb 15 '21 at 11:04
  • Its just an example, that describes in which way i intend to use class utilities, and from where i'd like to instanciate it, which will result in the expected outcome of my request which should be the "dummy" class name – Rolfsky Feb 15 '21 at 11:07

2 Answers2

1

Since you're instantiating utils as a static variable, at the time of its creation class dummy is not yet available so the answer is "no": you can't do that.

Alternative solution: "pass yourself in" (see code comments for explanations)

class utilities:

    def __init__(self):
        pass

    def utilMethod(self, obj):  # the caller is passed in
        print(obj.__class__.__name__) # this is how we can access the class-name of the caller
        pass

class dummy:
    utils = utilities()

    def dummyMthod(self):
        self.utils.utilMethod(self) # here we "pass ourselves in"


d = dummy()
d.dummyMthod() # prints "dummy"

UPDATE

If we want to declare utils as an object attribute (vs. static class attribute in the previous snippet), we can do:

class utilities:

    def __init__(self, obj):
        print(obj.__class__.__name__)
        pass

    def utilMethod(self, obj):
        pass

class dummy:

    def __init__(self):
        self.utils = utilities(self) # declare utils as object attribute inside the constructor and pass 'self' into utilities

    def dummyMthod(self):
        self.utils.utilMethod()


d = dummy() # prints "dummy"
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • Well no, `utils` is a class attribute defined outside of the constructor, its not static at all, while the solution is clever, I don't want to call utilMethod inside `dummyMethod`, will it help if utils was declared inside the constructor itself? – Rolfsky Feb 15 '21 at 11:13
  • @Rolfsky per a few different sources such as [this one](https://stackoverflow.com/a/68672/1057429) that's how you declare a static class variable, but of course I may be mistaken or using the wrong term. As for your followup question: if I understand correctly I think that the answer is "yes": if you declare `utils` as an object attribute (inside dummy's ctor), e.g.: `self.utils = utilities(self)` you should be able to use this exact same solution only by having `obj` passed as a constructor argument into `utilities` constructor – Nir Alfasi Feb 15 '21 at 11:20
  • 1
    Yup, thinking if there's any other way, done it with traceback aswell, but that's just ugly regex, update indeed, does what is required, thank you! – Rolfsky Feb 15 '21 at 11:35
0

Within __init__ (and generally within the methods of the class) you can use self.__class__ and/or self.__class__.__name__; the latter can be particularly useful for logging and similar messages.

self.logger = logging.getLogger(self.__class__.__name__)

(Or similar, perhaps also incorporating the module name.)

Jiří Baum
  • 6,697
  • 2
  • 17
  • 17
  • By calling `self.__class__.__name__` you'll get `"utilities"` not `"dummy"` as a result – Rolfsky Feb 15 '21 at 11:09
  • Ah, I've misread the question. You can get that through the `inspect` module, in particular `inspect.currentframe()` and/or `inspect.stack()`. – Jiří Baum Feb 15 '21 at 12:36