3

これを機能させるには複数の障害があり、おそらく不可能かもしれませんが、少なくとも質問したいと思いました...

したがって、AbstractEnumeratedConstantsGroup当然のことながら、subclassed が列挙された定数のグループを表すオブジェクトを作成するクラス ( returns 、returns 、returns 、returnsなどのFLAVORS('VANILLA', 'CHOCOLATE', 'STRAWBERRY')を含む) を作成するときに、メタクラスとその他のフットワークを使用するクラスがあります。新しい定数グループを作成するために必要なものは次のとおりです。FLAVORS[0]'VANILLA'FLAVORS[1]'CHOCOLATE'FLAVORS.VANILLA0FLAVORS.CHOCOLATE1

class FLAVORS(AbstractEnumeratedConstantsGroup):
    _constants = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')
FLAVORS = FLAVORS()

次のようにさらに削減したいと思います。

@enumerated_constants_group
FLAVORS = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')

乗り越える方法がわからない問題は次のとおりです。

    1. デコレーター コードから定義スコープからオブジェクトのラベル名を取得する適切な方法がない 2. クラス、メソッド、または関数ではないものをデコレートできない

ファクトリ/ビルダーの使用を検討しましたが、それについて気に入らないのは、コード内でグループ名を重複させる必要があること、またはグループに役に立たない__name__値があることです (これらは および で使用されます__repr__) __str__。元:

FLAVOR = enumerated_constants_group('FLAVOR', ('VANILLA', 'CHOCOLATE', 'STRAWBERRY'))

また

FLAVOR = enumerated_constants_group(('VANILLA', 'CHOCOLATE', 'STRAWBERRY'))
# FLAVOR.__name__ becomes some unfriendly machine-generated string

デコレーターのアイデアに代わるものとして、ファクトリ メソッドから (イントロスペクションを通じて、または関数に暗黙的に渡すことによって) 呼び出しスコープを参照して、メソッドを呼び出すと、新しく作成されたオブジェクトが呼び出し元の名前空間に挿入されるようにすることは可能でしょうか?与えられた名前?元:

enumerated_constants_group('FLAVOR', ('VANILLA', 'CHOCOLATE', 'STRAWBERRY'))
# I could now reference FLAVOR in any arbitrary scope that the method was called from

私が望むものを達成するためにできることはありますか?私が考えていない他のアプローチはありますか?

4

5 に答える 5

3

( のように) 素の名前に割り当てたときに何が起こるかに影響を与える一般的な方法はありませんFLAVORS = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')。だからあなたが望むことは不可能です。

FLAVORS = FLAVORS(...)つまり、返されたクラスをそれ自体のインスタンスに置き換えるメタクラスを作成できるため、最初の例の最後の行は必要ありません。オブジェクトを作成するには、クラス定義自体で十分です。

于 2012-08-02T18:43:47.460 に答える
2

http://code.activestate.com/recipes/413486/を見ましたか

次のようなコードを記述できます。

>>> from enum import enum
>>> FLAVORS = enum('VANILLA', 'CHOCOLATE', 'STRAWBERRY')
>>> print FLAVORS
enum (VANILLA, CHOCOLATE, STRAWBERRY)
>>> print FLAVORS.VANILLA
VANILLA
>>> f = FLAVORS.CHOCOLATE
>>> f in FLAVORS
True
>>> for f in FLAVORS:
...     print f
...
VANILLA
CHOCOLATE
STRAWBERRY
于 2012-08-02T18:53:08.833 に答える
0

名前付きタプルはどうですか。http://docs.python.org/library/collections.html#collections.namedtuple

于 2012-08-03T20:33:34.483 に答える
0

中間ステップとして、次のことができます

FLAVORS = type("FLAVORS",
               (AbstractEnumeratedConstantsGroup,),
               {_constants = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')})()

これは偽のデコレータにつながります

def enumerated_constants_group(*args):
    AECG=AbstractEnumeratedConstantsGroup
    t = type(args[0], (AECG,), dict(_constants=args[1:]))
    return t()

FLAVORS = enumerated_constants_group('FLAVORS', 'VANILLA', 'CHOCOLATE', 'STRAWBERRY')
于 2012-08-02T18:44:32.770 に答える
0

関数/メソッド デコレーターの他に、クラス デコレーターもあります (少なくとも Python 2.4 にはありました) 。http: //www.python.org/dev/peps/pep-3129/ を参照してください。

とにかく、これがあなたが必要としているものかどうかはわかりません。

(型、値) を引数として取得するファクトリ クラスを使用します。

1 つの注意: コードがこのようなもので、AbstractEnumeratedConstantsGroup が機能を追加しない場合、タプルを使用しないのはなぜですか?

次の内容で constants.py モジュールを定義できます。

FLAVOURS = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')
PETS = ('DOG', 'CAT', 'FISH')

コードからこれらのタプルを使用します。

import constants
for pet in constants.PETS:
    print 'I have a ', pet
于 2012-08-02T18:47:39.277 に答える