5

使用シナリオ:

# 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の先頭に多くの重複コードを追加する必要のないソリューションをいただければ幸いです。test...()

センチネルの例について読みましたが、これはクラスでは機能せず、グローバル変数を追加してセンチネル オブジェクトを内部に保持したくありません。

4

3 に答える 3

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

2 つの核となるアイデア: キーワード パラメータ dict にローカルでオーバーライドされる (またはオーバーライドされない) 名前付き値のセットをキャプチャします。センチネルオブジェクトをデフォルト値として使用して、特定の名前付き引数が明示的に渡されたかどうかを一意に識別します (Noneこの目的でよく使用されますが、ここのようNoneに、パラメーターの「ファーストクラスの値」として必要な場合は、一意のセンチネル オブジェクトでも同様です)。

于 2010-08-25T15:38:59.547 に答える
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が必要です。他のセンチネル値を選択した場合は、これをなくすことができます (ただし、最も一般的な値です)。NoneMyClass.testNone
  • クラスまたはインスタンスのデフォルトが必要かどうかは、元の質問では不明でした。上記のものはインスタンスのデフォルトです。つまり、すべてのMyClassインスタンスのデフォルトのロガーは、コンストラクターNoneで設定されます。MyClass
于 2010-08-25T15:38:29.767 に答える
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がキーワード引数として渡された場合、ロガーは使用されません。

于 2010-08-25T15:38:36.537 に答える