如何在Python中检测callee类的staticmethod / classmethod?

时间:2012-09-28 10:06:55

标签: python class-method

我在这里发现了类似的问题,但我的问题有点不同...... 我在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”类名?

(我知道这非常不合适,可能在编写得很好的程序中也没用,但无论如何......)

3 个答案:

答案 0 :(得分:2)

您是否考虑过编写类似实现的日志记录模块。像下面这样的东西

制作一个单独的Logger类。当您需要记录器对象时,请调用Logger.get_logger(your_class_name)。此方法要么创建新的记录器并将其返回,要么返回已创建的特定记录器名称的Logger。然后使用此记录器。

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

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))

答案 1 :(得分:1)

这不是最好的设计,伐木是"单身"有它的所有缺点,但如果你愿意接受,那么你的问题有一些语言支持。您可以通过检查堆栈来获取调用者:

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()

答案 2 :(得分:0)

如您所知,Python中的所有内容都是Object ..所以,您实际上可以将Class Object作为参数传递给您的方法..

因此,您可以像这样更改方法定义: -

class MyUtil(object):

    @staticmethod
    def log(message, level, ClassName):

并将调用类的对象传递给此方法: -

class Deployer(object):

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