使用场景:
# 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对象。
答案 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
作为关键字参数传递,则不使用记录器。