2017-07-03 1 views
0

私は次のようにコンパス指示のEnumクラスを持っています。 私は同じクラスで宣言された '反対のもの'を持っています。Python 3.6で静的なdictにアクセス

from enum import Enum 

class Compass(Enum): 
    N = 'N' # North 
    S = 'S' # South 
    E = 'E' # East 
    W = 'W' # West 
    opposites = {N: S, S: N, E: W, W: E} 

    # static method to provide the opposite values. 
    @staticmethod 
    def other(com): 
     return opposites[com] 

私が他の電話をかけようとすると、 Compass.other(Compass.N)、私はCompass.Sを得ることを期待、代わりに私は何が起こっている。..

TypeError: 'Com' object is not subscriptable 

を取得していますし、どのように私はこのpythonicallyを改善することができますか?

答えて

2

基本的な問題は、oppositeEnum体に変換されることであるばかりN,E、およびWです。次の問題はoppositeの値です - 彼らはではありません。Enumに変換されます。

理想的には、我々のようなものだろう:

# NB: does not currently work! 

class Compass(Enum): 
    N = 'N', S 
    S = 'S', N 
    E = 'E', W 
    W = 'W', E 

Compass.E.opposite is Compass.W # True 

を、これは現在動作しない理由は2つあります:

  • クラスがされた後Enumメンバーに平野値から、最終的な変換が起こります作成された
  • 前方参照は許可されません。

したがって、クリーンな実装とAPIを得るためには、Enumを後処理する必要があります。これはとてもクールです

@reverse({'N':'S', 'E':'W'}) 
class Compass(Enum): 
    N = 'N' # North 
    S = 'S' # South 
    E = 'E' # East 
    W = 'W' # West 

>>> Compass.N.opposite is Compass.S 
True 
+0

class reverse(): "decorator to add reverse lookups to Enum members" def __init__(self, reverse_map): "initialize decorator by saving map" self.reverse_map = reverse_map def __call__(self, enum): "apply map to newly created Enum" for first, second in self.reverse_map.items(): enum[first].opposite = enum[second] enum[second].opposite = enum[first] # don't forget to return the now-decorated Enum return enum 

と、使用中:私は、デコレータを使用します。私はこの答えから最後の数日より多くのPythonを学びました。 – Konchog

+1

@ Konchog:高い評価!ありがとうございました! –

1

@RomanPerekhrestは純粋にレスポンスの速さのためにこの点で功績が認められましたが、私が望むものを得るためにはもっと喧嘩しました。これはクラスの列挙です。入力が不正な場合、Enum自体にキャストするとエラーが発生します。

私にとってうまくいったクラスファイルfolloeinh RomanPerekhrestはこのように見えます。

from enum import Enum 

class Compass(Enum): 
    N = 'N' # North 
    S = 'S' # South 
    E = 'E' # East 
    W = 'W' # West 
    _opposites = {N: S, S: N, E: W, W: E} 

    @staticmethod 
    def other(item): 
     return Compass(Compass._opposites.value[item.value]) 

if __name__ == "__main__": 
    print(Compass.other(Compass.E)) 

しかし、EthanFurmanの応答が美しいです、と私は実際に

1

カスタムクラスCompass列挙あるEnumクラスから派生している...私は完全にそれをまだ理解していないこと、という実装@しかし、添字のない配列。

は、この行を考えてみましょう:

print(type(Compass.N)) 

あなたが出力<class 'str'>にそれを期待していますが - それは出力:

<enum 'Compass'> 

enumarationオブジェクトプロパティの使用にvalue属性にアクセスするには。

print(Compass.N.value)   # prints "N" 
print(Compass.opposites.value) # prints {'S': 'N', 'N': 'S', 'E': 'W', 'W': 'E'} 

適切Compass.other()関数宣言は以下のようになります

# static method to provide the opposite values. 
    @staticmethod 
    def other(item): 
     if item in Compass.opposites.value: 
      return Compass.opposites.value[item] 
     else: 
      raise AttributeError('unknown compass direction :', item) 

使用:

print(Compass.other(Compass.N.value)) # prints "S" 
関連する問題