如何在Python中检测staticmethod/classmethod的被调用类?

如何在Python中检测staticmethod/classmethod的被调用类?,python,class-method,Python,Class Method,我在这里发现了类似的问题,但我的问题有点不同。。。 我在MyUtil类中使用log()函数作为staticmethod: class MyUtil(object): @staticmethod def log(message, level): ... 但是现在我必须知道这个staticmethod是从哪个类/对象调用的? 例如: class Deployer(object): def deploy(self): ... MyU

我在这里发现了类似的问题,但我的问题有点不同。。。 我在MyUtil类中使用log()函数作为staticmethod:

class MyUtil(object):

    @staticmethod
    def log(message, level):
    ...
但是现在我必须知道这个staticmethod是从哪个类/对象调用的? 例如:

class Deployer(object):

    def deploy(self):
        ...
        MyUtil.log ("Starting deployment", "info")
        ...
是否可以从MyUtil.log函数获取并记录此“Deployer”类名


(我知道这是非常不面向对象的,在一个编写良好的程序中可能永远不会有用,但无论如何……)

正如您所知,Python中的一切都是对象。。因此,实际上可以将
类对象
作为参数传递给方法

因此,您可以按如下方式更改方法定义:-

class MyUtil(object):

    @staticmethod
    def log(message, level, ClassName):
并将调用类的对象传递到此方法:-

class Deployer(object):

    def deploy(self):
        ...
        MyUtil.log ("Starting deployment", "info", Deployer)

你是否考虑过编写一个日志模块,比如实现?像下面这样的

制作一个单独的记录器类。当您需要logger对象时,请调用logger.get\u logger(您的\u类\u名称)。此方法可以创建一个新的记录器并将其返回,也可以返回已为该特定记录器名称创建的记录器。然后使用这个记录器

这样,您可以在需要时随时使用标准记录器更改自己的记录器。开发人员将熟悉您使用的方法

logger = Logger.get_logger(Deployer.__class__.__name__)
logger.info("Starting deployment")
下面是一个非常简单的记录器实现

"""
Sample logger implementation
"""
import datetime


class Logger:
    """
    Main logger class
    """
    _cached_loggers = dict()

    def __init__(self, logger_name):
        self.name = logger_name
        self._cached_loggers[logger_name] = self

    @classmethod
    def get_logger(cls, logger_name):
        """
        Return a new logger or already existed one
        """
        if logger_name in cls._cached_loggers:
            logger = cls._cached_loggers[logger_name]
        else:
            logger = Logger(logger_name)
        return logger

    def info(self, msg):
        """
        logging info logs
        """
        print u"{0} - {1} - {2}".format(self.name,
                                        datetime.datetime.now(),
                                        unicode(msg))

这并不是最好的设计,日志记录是一个“单例”,有其所有的缺点,但如果你愿意接受这一点,有一些语言支持你的问题。您可以通过检查堆栈来获取调用者:

import inspect

class MyUtil(object):
    @staticmethod
    def log(message, level):
        frame, module, line, function, context, index = inspect.stack()[1]
        self_name = frame.f_code.co_varnames[0]  # Name of the first argument (usually 'self')
        instance = frame.f_locals[self_name]
        class_name = instance.__class__.__name__
        print class_name

class Deployer(object):
    def deploy(self):
        MyUtil.log ("Starting deployment", "info")

Deployer().deploy()

您可以将
classname
作为参数传递..包含对您发现的类似问题的引用会很方便。这将帮助人们知道什么不是你想要的答案,并将帮助人们在将来找到这个问题,他们想要的答案是你的一个类似的答案:)@JonClements,谢谢,我在发布我的问题时有几个类似的问题,但当我试图编辑问题时-没有更多。我下次再做。:)请添加一个小的Logger示例类好吗?谢谢,这是一个更好的解决方案,但它需要一些重构工作。“我会考虑的。”deniszh另一个解决方案是只使用标准日志模块。并根据需要更改日志处理程序。下面是一些标准日志处理程序,其中一个可能适合您的需要。如果他们不这样做,您可以自己编写一个日志处理程序,正如在这个问题中所解释的。谢谢,这是我真正想做的,但正如我发现的,有时我需要深入堆栈以获得正确的类名。。。也许重写日志记录会更好,但无论如何:)