2012-09-28 39 views
2

我发现类似的问题在这里,但我的问题是有点不同...... 我的日志()函数中MyUtil类静态方法:如何在Python中检测staticmethod/classmethod的被调用类?

class MyUtil(object): 

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

,但现在我必须知道从哪个类/对象这个静态方法被称为? 例如:

class Deployer(object): 

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

是否有可能得到和日志MyUtil.log功能这个“部署”类的名字?

(我知道,这是非常不OO并可能在一个良好的书面程序永远是有用的,但无论如何...)

+0

您可以通过'classname'作为参数.. –

+1

这将是得心应手包括给你发现了类似的问题,引用。这将帮助人们知道什么不是你所追求的答案,并将在未来帮助他们,因为他们可能会发现这个问题,他们所追求的答案是类似的答案:) –

+0

@JonClements,谢谢,当我发布我的时候,有几个类似的问题,但是当我尝试编辑问题 - 没有更多。 下次会做。 :) – deniszh

回答

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

谢谢,这是我真的想要做的,但是因为我发现我需要时常深入堆栈以获得正确的类名......也许它会更好地重写日志记录,但无论如何:) – deniszh

0

正如你所知道的一切在Python的对象。所以,你其实可以通过Class Object作为参数传递给你的方法..

所以,你可以改变你的方法定义是这样的: -

class MyUtil(object): 

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

,并调用类的对象传递到该方法: -

class Deployer(object): 

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

你有没有考虑写一个日志模块,如实现。类似如下

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

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

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

你可以 - 请添加一个小记录器的例子类? – Thomas

+0

谢谢,这是更好的解决方案,但它需要一定量的重构工作。会考虑一下。 – deniszh

+0

@deniszh另一种解决方案是使用标准日志记录模块。并根据您的需求更改您的日志处理程序。以下是一些标准日志处理程序,其中一个可能适合您的需求http://docs.python.org/library/logging.handlers.html。如果他们不这样做,你可以只写一个日志处理程序你自己在这个问题中解释http://stackoverflow.com/questions/3118059/how-to-write-custom-python-logging-handler。 – yilmazhuseyin

相关问题