DennisLi
DennisLi

Reputation: 4154

How can I tell a function of parent class is called by classmethod or instance method from child class?

For instance:


class TestParent(object):
    # I need a function to be compatible with both classmethod and instance method.
    @property
    def log(cls, self=None):
        if "it's called from a child classmethod":
            return logging.root.getChild(cls.__class__.__module__ + '.' + cls.__class__.__name__)
        if "it's called from a child object":
            return logging.root.getChild(self.__class__.__module__ + '.' + self.__class__.__name__)



class TestChild(TestParent):
    @classmethod
    def test(cls):
        cls.logger.info('test')

    def test2(self):
        self.logger.info('test2')

child = TestChild()
child.test()
child.test2()

Is there any way to achieve this?

Upvotes: 1

Views: 69

Answers (1)

snakecharmerb
snakecharmerb

Reputation: 55799

You can do something like what you want by using a staticmethod instead of a property, passing the caller's cls or self and testing whether it's a class object or not:

import logging

logging.basicConfig(level=logging.INFO)


class TestParent(object):
    # I need a function to be compatible with both classmethod and instance method.
    @staticmethod
    def logger(obj):
        if isinstance(obj, type):
            return logging.root.getChild(obj.__class__.__module__ + '.' + obj.__class__.__name__)
        else:
            return logging.root.getChild(obj.__class__.__module__ + '.' + obj.__class__.__name__)

Output:

INFO:builtins.type:test
INFO:__main__.TestChild:test2

Having said that, it's more usual in Python to define a module per logger rather than per class. Unless there is real value to be gained from having per-class loggers I'd go with one per module.

Upvotes: 1

Related Questions