如何在默认为类级别值的Python方法中使用命名参数?

时间:2010-08-25 15:32:05

标签: python named-parameters

使用场景:

# case #1 - for classes
a = MyClass() # default logger is None
a = MyClass(logger="a") # set the default logger to be "a"
a.test(logger="b") # this means that logger will be "b" only inside this method
a.test(logger=None) # this means that logger will be None but only inside this method
a.test() # here logger should defaults to the value specified when object was initialized ("a")

如何实施MyClass以便能够如上所述使用它?

假设我在MyClass内有几个可以接受logger命名参数的方法,所以我很感激一个解决方案,它不需要在每个开头添加大量重复代码{ {1}}方法。

我读到了sentinel example,但这不适用于类,我不想添加一个全局变量来保存sentinel对象。

3 个答案:

答案 0 :(得分:9)

_sentinel = object()

class MyClass(object):
  def __init__(self, logger=None):
    self.logger = logger
  def test(self, logger=_sentinel):
    if logger is _sentinel: logger = self.logger

# in case you want to use this inside a function from your module use:
_sentinel = object()
logger = None
def test(logger=_sentinel)
    if logger is _sentinel: logger = globals().get('logger')

两个核心思想:捕获可能(或可能不是)本地覆盖到关键字参数dict的命名值集合;使用sentinel对象作为默认值来唯一标识是否已明确传递某个命名参数(None通常用于此目的,但在此处,您需要None作为参数的“第一类值”,一个唯一的sentinel对象也可以。)

答案 1 :(得分:3)

class MyClass(object):    
    def __init__(self, logger=None):
        self.logger = logger
    def test(self, **kwargs):
        logger = kwargs.get("logger", self.logger)
        # use logger, which is sourced as given in OP

备注

  • 由于**kwargs中的记录器命名变量允许None值,因此必须使用MyClass.test。如果您选择了其他一些标记值(但None最常见),您可以取消此操作。
  • 原始问题中不清楚是否需要类或实例默认值。上面给出的是一个实例默认值,即所有MyClass个实例的默认记录器None,在MyClass构造函数中设置。

答案 2 :(得分:1)

class MyClass(object):
    def __init__(self, logger = None):
        self.logger = logger

    def test(self, **kwargs):
        logger = self.logger            
        if kwargs.has_key("logger"):
            logger = kwargs.get(logger)
        print "logger is %s" logger.name

简要说明:test首先假设它将使用实例记录器。但是,如果将显式记录器作为命令行参数传入,则将使用它。如果logger = None作为关键字参数传递,则不使用记录器。