3

クラスと関数があるとします。

class AddressValidator(self):
    def __init__(self):
        pass
    def validate(address):
        # ...

def validate_address(addr):
    validator = AddressValidator()
    return validator.validate(addr)

この関数は、クラスを使用するためのショートカットです。では、この関数を何千回も実行する必要がある場合はどうなるでしょうか。データベースへの接続など、バリデータクラスが実際にインスタンス化で何かをしなければならない場合、それを何千回も何度も作成するのはかなり無駄です。私はおそらくこのようなことができるかどうか疑問に思っていました:

def validate_address(addr):
    if not hasattr(validate_address, 'validator'):
        validate_address.validator = AddressValidator()

    validator = validate_address.validator
    return validator.validate(addr)

これで、バリデータ クラスは 1 回だけインスタンス化され、「関数内」に保存されます。ただし、これが行われたのを見たことがないので、悪い習慣だと思います。もしそうなら、なぜですか?

注: モジュール グローバルにバリデータ オブジェクトをキャッシュするだけでよいことはわかっています。モジュールのポイ捨てを避けたいときに、これが実行可能な解決策であるかどうか、私はただ興味があります。

4

2 に答える 2

3

デフォルトの引数を使用します (関数定義時に 1 回評価され、関数にバインドされます)。

def validate_address(addr, validator=AddressValidator())
    return validator.validate(addr)

のインスタンスが不変であると見なされる場合 (つまり、内部状態を変更するメソッドが含まれていない場合)、これは完全に受け入れAddressValidatorられます。また、必要に応じて後でバリデーターの選択をオーバーライドすることもできます (たとえば、特殊なバリデーターを提供するため)。特定の国向け)。

于 2012-09-18T05:52:43.547 に答える
3

「すべてがオブジェクト」であるにもかかわらず、適切に制御されたクラスのインスタンスほどうまく機能するわけではありません。この問題は、Python で呼び出された" functor " または " callable object " の典型的なケースのように見えます。

コードは次のようになります

class AddressValidator(self):
    def __init__(self):
        pass
    def __call__(self,address):
        # ...

validate_address = AdressValidator()

または、バインドされたメソッドへのショートカットとして関数を定義することもできます

class AddressValidator(self):
    def __init__(self):
        pass
    def validate(self,address):
        # ...

validate_adress = AdressValidator().validate
于 2012-09-18T06:04:36.223 に答える