0

基本クラスBaseと 2 つのサブクラスがFooありBarます。Baseオプションの引数を持つ関数を定義します。この引数は、(定義時ではなく) 実行時に指定またはフェッチされます。引数は常にまったく同じ方法で取得されるため、サブクラスには定型的なコード行が含まれます (確かに 1 行ですが、これは単なる例です)。通常、これは次のようになります。

class Base(object):
    def greet(self, name=None):
        pass

class Foo(Base):
    def greet(self, name=None):
        name = name or get_name_at_runtime()
        print('Hello {name} this is Foo.'.format(name=name))

class Bar(Base):
    def greet(self, name=None):
        name = name or get_name_at_runtime()
        print('Hello {name} this is Bar.'.format(name=name))

今、この問題を解決するハックを思いつきましたが、これが確実な解決策であるとは思いません. この解決策には、オーバーライドされたメソッドをラップして正しい値を提供するプライベート メソッドを定義することが含まれます。両方のメソッドが切り替えられる__init__ため、メソッドの呼び出し/オーバーライドは「正常」に感じられます。

class Base(object):
    def __init__(self):
        self.greet, self.__greet = self.__greet, self.greet

    def greet(self, name):
        pass

    def __greet(self, name=None):
        self.__greet(name or get_name_at_runtime())

class Foo(Base):
    def greet(self, name):
        print('Hello {name} this is Foo.'.format(name=name))

class Bar(Base):
    def greet(self, name):
        print('Hello {name} this is Bar.'.format(name=name))

私が思いついた「解決策」は、デフォルト値がないように見えるため、名前がオプションであることが明確ではないという問題を引き起こします。

場合によってBaseは抽象基本クラスであり、そうでない場合もあるため、両方をサポートするソリューションを探しています。

4

2 に答える 2

0

デコレータを使用するのはどうですか?これは、彼らが意図していることのようなものです。何かのようなもの:

def get_at_runtime(func):
    def wrapped(*args, **kwargs):
        if kwargs.get('name', None) is None:
            kwargs['name'] = get_name_at_runtime()
        func(*args, **kwargs)

メソッドをラップします。

@get_at_runtime
def greet(self, name=None):
    print('Hello {name} this is Foo.'.format(name=name))
于 2013-05-31T08:33:44.670 に答える