Как использовать именованные параметры в методах Python, которые по умолчанию соответствуют значению уровня класса?
Сценарий использования:
# 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
named, поэтому я был бы признателен за решение, которое не требует добавления большого количества дубликатов кода в начале каждого метода test...()
.
Я читал о примере дозорного , но это не работает для классов, и я бы не хотел добавлять глобальную переменную, чтобы внутри объекта-дозорника.
_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')
две основные идеи: захват набора именованных значений, которые могут быть (или могут отсутствовать) локально переопределены в keywords-parameters dict; используя объект-опознаватель в качестве значения по умолчанию, чтобы однозначно идентифицировать, был ли явно передан определенный именованный аргумент или нет (для этой цели часто используется None
( None
), но когда, как здесь, вы хотите, чтобы None
как «значение первого класса» для параметра , уникальный объект-дозорный будет делать то же самое).
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
для переменной logger с именем вMyClass.test
. Вы могли бы покончить с этим, если бы выбрали какое-то другое значение дозорного (ноNone
самое распространенное). - В первоначальном вопросе неясно, нужен ли вам класс или экземпляр по умолчанию. Тот, который указан выше, является экземпляром по умолчанию, то есть регистратором по умолчанию во всех экземплярах
MyClass
являетсяNone
, установленным в конструктореMyClass
.
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
передается в качестве аргумента ключевого слова, то регистратор не используется.