2016-04-23 18 views
0

ためのキー、値の型を指定して、私はPythonの型のヒント - dictのサブクラス

class A(dict): pass 

がのキーと値の種類を指定する方法はあり持っていると言いますか?タイプが継承されるようにすることができますか?class B(A)はキーのタイプ値を継承し、値のタイプをオーバーライドできますか?

これはpep-0484で導入されたタイプヒントを介して行われるのが理想的ですが、私はPython 2を使用しているので、タイプコメント付きのソリューションが必要です。しかし、これが不可能な場合は、メタクラスやその他のハックを含む解決策が受け入れられるでしょう。

+0

*「タイプコメント」*とはどういう意味ですか?あなたは実際に型を強制したいのですか、それとも単にドキュメント化したいのですか? – jonrsharpe

+0

@jonrsharpe:[PEP 484 *タイプコメント*](https://www.python.org/dev/peps/pep-0484/#type-comments) –

+0

@MartijnPietersああありがとう、私はOPが参考にしていたかどうか疑問に思ったドキュメンタリーや何かに – jonrsharpe

答えて

2

クラスとのすべてのタイプのやりとりはメソッドを経由するので、それらのメソッドに注釈を付けます。 A.__setitem__(self, key, value):は、キーと値のペアを設定するために呼び出され、期待される型を示すために注釈を付けることができます。

Python 2との互換性が必要な場合は、タイプコメントを含め、ここで有効なPEP 484注釈があります。

Bがメソッドをオーバーライドしない限り、これらのアノテーションはBに継承されます。

+0

ありがとうございます - 型情報が他のメソッドに伝播するか、それらに注釈を付ける必要がありますか? –

+0

@Mr_and_Mrs_D: 'dict'型自体に注釈がないので、サブクラス化するときにすべてのメソッドに注釈を付ける必要があります。 –

+0

私の編集を参照してください - 最終的にキー変数/値型をクラス変数として指定し、この情報をすべての組み込みメソッドに伝える魔法の方法はありませんか? –

0

@MartijnPieters answer

_key_type_global = unicode 

class A(dict): 

    _key_type = unicode 

    def __setitem__(self, key, value): 
     """A._key_type is not recognised, _key_type_global is 
     :type key: _key_type_global 
     :type value: int 
     """ 
     super(A, self).__setitem__(key, value) 

class B(A): pass 


a = A() 
a['str'] = 'uy' # expected type unicode got str instead 
a[u'str'] = 'uy' # no warn (?) 
a[u'str'] = 1 # no warn 

val = a[u'str'] # Pycharm does not give any type info on value so I have to 
# define __getitem__ too 

# type info is inherited 
b = B() 
b['str'] = 'uy' # expected type unicode got str instead 
b[u'str'] = 'uy' # no warn (?) 
b[u'str'] = 1 # no warn 

だから1は、すべてのメソッドをオーバーライドする必要があります(私は、以下の動作が原因標準またはIDEのバグ/機能であってよいPycharm 5.0.4を使用しています)(キーにエラボレーション値型情報は個々のメソッドに対してローカルです)。 IOWは、1が行うことができますパラメータや属性などのためのケースとは異なり:

class A(dict): # type dict[unicode, int]

はさらに種類を指定できるようにする手立てがないように思える:

class A(object): 

    def __init__(self, dct): 
     self.dct = dct # type : dict[unicode, int] 

これはNOOPですクラス変数として、サブクラスで簡単にオーバーライドすることができます。

関連する問題