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)
これを行う方法はありますか?
これを行わず、抽象基本クラス( 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
このプロジェクトに参加しているのは私だけではないので、誰かが誤ったデータ型でRegisterAsListener関数を呼び出さないようにします。
関数を完全に文書化してから、誤ったパラメーターで例外をスローさせます。 RegisterAListener
のユーザーは、ドキュメントを使用して、関数が期待するデータの種類を知ることができます。また、誤ったパラメーターが指定された場合、結果として生じる例外により、RegisterAListener
のユーザーが何であるかが明確になります。間違っていた。