2013-02-13 11 views
9

私はリストにインターフェースを追加するPythonクラスの関数を持っています。関数のパラメータ型をPythonで強制しますか?

def RegisterAsListener(self, inListener): 
    self.__TransitListeners.append(inListener) 

クラスはちょうど私のインターフェイスは、このオブジェクトをつかむとから継承し、すべての更新のために自身を登録する必要がありますので、これは、いいです。

class ITransit(): 
    def TransitUpdate(self, data): 
     raise NotImplementedError("You must define this function.") 

(私が正しくインターフェイスを作ったと仮定した場合)

私はこのプロジェクトの一つだけではないですので、私は誰かが不正なデータ型にRegisterAsListener関数を呼び出す必要はありません。私は、レジスタ関数内の型をチェックするコードを入れることができますが、コンパイラが間違ったデータ型で押してみるときにプログラマーがただ叫んでいたとすれば、ずっと簡単です。

def RegisterAsListener(self, IListener inListener): 
    self.__TransitListeners.append(inListener) 

これを実行する方法はありますか?

+12

'ちょうどコンパイラであればプログラマーに叫んだ。どのコンパイラ? – Abhijit

+2

'abc'モジュールを使用して、オブジェクトが代わりに実装すべきものを定義します。 –

+0

それ以外の場合、Pythonは*動的に型指定された*言語であり、オブジェクト型を強制しません。 –

答えて

6

これを実行しないで、抽象基本クラス(http://docs.python.org/2/library/abc.html)を使用して特定のメソッドの実装のみを強制することを強くお勧めしますが、これも可能です。

ここではそのような何かを行う方法の例です:http://www.artima.com/weblogs/viewpost.jsp?thread=101605

# mm.py 
registry = {}                 

class MultiMethod(object):              
    def __init__(self, name):             
     self.name = name               
     self.typemap = {}              
    def __call__(self, *args):             
     types = tuple(arg.__class__ for arg in args) # a generator expression! 
     function = self.typemap.get(types)          
     if function is None:              
      raise TypeError("no match")           
     return function(*args)             
    def register(self, types, function):           
     if types in self.typemap:            
      raise TypeError("duplicate registration")       
     self.typemap[types] = function           

def multimethod(*types):               
    def register(function):              
     function = getattr(function, "__lastreg__", function)     
     name = function.__name__             
     mm = registry.get(name)             
     if mm is None:               
      mm = registry[name] = MultiMethod(name)        
     mm.register(types, function)            
     mm.__lastreg__ = function            
     return mm                
    return register                

    if hasattr(function, "__lastreg__"):           
     function = function.__lastreg__ 

そして、それを使用してコード:

import mm                  

@mm.multimethod(int)                
def spam(a):                  
    print 'Calling the int method'            
    print '%s: %r' % (type(a), a)            

@mm.multimethod(float)               
def spam(a):                  
    print 'Calling the float method'            
    print '%s: %r' % (type(a), a)            

spam(5)                   
spam(5.0) 

出力例:

Calling the int method 
<type 'int'>: 5 
Calling the float method 
<type 'float'>: 5.0 
7

私はこのプロジェクトの一つだけではないですので、私は、間違ったパラメータが投げてみましょう、誰か は

ドキュメント徹底的に機能不正なデータ型にRegisterAsListener関数を呼び出す必要はありません例外。 RegisterAListenerのユーザーは、関数が期待するデータの種類を知るためにドキュメントを使用できなければなりません。また、誤ったパラメータが与えられた場合は、RegisterAListenerのユーザーが何を誤ったのかを明確にする必要があります。

+1

ドキュメントのある公正なポイントは、より良いルートかもしれません。 – MintyAnt

+3

ドキュメンテーションの一部として[Python Annotations](http://www.python.org/dev/peps/pep-3107/)を使用することをお勧めします。 – kojiro

関連する問題