16

一部の関数は、パラメーター化されない「定数」値 (つまり、後で再定義されるように設計されていない) を必要とします。デフォルトの引数はfunction ごと1 回だけ保存されますが、一部の引数はパラメーターとして (つまり、署名の一部として) 入れてもあまり意味がありません。(あまり役に立たない)例:

def foo(bar):
    my_map = {"rab": barType, "oof": fooType}
    return my_map.get(bar,defaultType)()

呼び出しごとにそのような定数を再定義するために、CPU 時間と RAM スペースが浪費されていました。他のいくつかの方法は、そのような定数をモジュールレベルのグローバルとして保存するか、関数を呼び出し可能なクラスにすることですが、他の方法があるかもしれません.

モジュール レベルのグローバルな方法を実行する場合、(意味する) 定数変数の前に "_" を付けて、それが誰の利益にもならないことを示します。それでも、モジュールの名前空間がわずかに「汚染されている」感じています。

_my_map = {"rab": barType, "oof": fooType}
def foo(bar):
    return _my_map.get(bar,defaultType)()

または、それをクラスの方法に変換します。インスタンスを作成__call__する必要を避けるために、クラスメソッドを作成します。

class foo:
   my_map = {"rab": barType, "oof": fooType}
   @classmethod
   def __call__(cls,bar):
       return cls.my_map.get(bar,defaultType)()

これらのソリューションはPythonicで十分ですか?

これを行う他の方法はありますか?

そのような「定数」を使用する練習としても問題ありませんか?

私の例のこれらのオブジェクトは、必ずしも実際の定数ではありませんが、目的によってそのように使用されている (および考えられる)ことに注意してください。

4

4 に答える 4

17

関数の属性として設定します。

def foo(bar):
    return foo.my_map.get(bar, defaultType)()
foo.my_map = {"rab": barType, "oof": fooType}

呼び出し可能なクラスまたはクロージャーは、IMO としては十分に単純ではありません。

于 2013-03-19T09:18:13.217 に答える
5

IMHO、モジュールレベルの定数に問題はありません。

PEP 8によると、定数は次のようにすべて大文字にする必要があることに注意してください。

_MY_MAP = {"rab": barType, "oof": fooType}
def foo(bar):
    return _MY_MAP.get(bar,defaultType)()

標準ライブラリの正規表現モジュールはこのスタイルを使用しており、多くの確立されたサードパーティ ライブラリも同様です。確信が持てない場合は、site-packagesディレクトリに移動して grep してください:

egrep "^_?[A-Z]+ =" *
于 2013-03-19T10:38:41.613 に答える
3

クロージャを使用することもできます:

def make_foo():
    my_map = {"rab": barType, "oof": fooType}
    def foo(bar):
        return my_map.get(bar,defaultType)()
    return foo
foo = make_foo()
于 2013-03-19T09:18:21.387 に答える
1

可能な限り自己完結型のものを作ること。関数オブジェクト(別名functor)クラスを作成し、それに__call__()メソッドまたはclassmethod(おそらく両方ではない)を与えることができます:

class bazType(object): pass
class barType(object): pass
class fooType(object): pass

class Foo(object):
    _DEFAULT_TYPE = bazType
    _MY_MAP = {"rab": barType, "oof": fooType}

    def __call__(self, bar):
        return self._MY_MAP.get(bar, self._DEFAULT_TYPE)()

    @classmethod
    def foo(cls, bar):
        return cls._MY_MAP.get(bar, cls._DEFAULT_TYPE)()

# using classmethod
print Foo.foo("rab")

# using __call__ method
foo = Foo()
print foo("baz")

# alternative way to use classmethod
foo = Foo.foo
print foo("oof")

さらに別の方法は、を定義することstaticmethodです。これは、他の2つと非常に似ているため、説明しませんが、私が望むアイデアが得られます。

于 2013-03-19T12:06:30.203 に答える