isinstance()
またはインターフェースの前にポリモーフィズムとダックタイピングを使用する
通常、オブジェクトで何をしたいのかを定義してから、ポリモーフィズムを使用して各オブジェクトが実行したいことにどのように応答するかを調整するか、ダックタイピングを使用します。手元のオブジェクトが最初にやりたいことを実行できるかどうかをテストします。これは、呼び出しとイントロスペクションのトレードオフであり、従来の知識では、イントロスペクションよりも呼び出しの方が望ましいとされていますが、Pythonでは、テストよりもダックタイピングが優先されisinstance
ます。
したがって、そもそも何かが反復可能であるかどうかをフィルタリングする必要がある理由を理解する必要があります。なぜあなたはこれを知る必要があるのですか?try: iter(object)
、を使用しexcept TypeError: # not iterable
てテストします。
または、渡されたものが反復可能でない場合は、エラーを通知するため、例外をスローする必要があります。
ABC
ダックタイピングでは、複数の方法をテストする必要がある場合があるため、isinstance()
テストの方が適している場合があります。このような場合、Abstract Base Class(ABC)を使用することもオプションになる可能性があります。ABCを使用して、たとえば、特定の操作に適したタイプとして、いくつかの異なるクラスを「ペイント」しましょう。ABCを使用して、使用する特定の実装ではなく、実行する必要のあるタスクに焦点を当てましょう。あなたはPaintable
ABC、Printable
ABCなどを持つことができます。
Zopeインターフェースとコンポーネントアーキテクチャ
アプリケーションが非常に多くのABCを使用している場合、またはさまざまな状況に対処するためにクラスにポリモーフィックメソッドを追加し続ける必要がある場合、次のステップは、 Zopeコンポーネントアーキテクチャなどの本格的なコンポーネントアーキテクチャの使用を検討することです。(ZCA)。
zope.interface
インターフェースは、特にZCAアダプターと組み合わせた場合、ステロイドのABCです。インターフェイスは、クラスの予想される動作を文書化します。
if IFrobnarIterable.providedBy(yourobject):
# it'll support iteration and yield Frobnars.
ただし、アダプタを検索することもできます。クラスでシェイプを使用するたびにすべての動作を配置する代わりに、特定のユースケースにポリモーフィックな動作を提供するアダプターを実装します。オブジェクトを、印刷可能、反復可能、またはXMLにエクスポート可能に適合させることができます。
class FrobnarsXMLExport(object):
adapts(IFrobnarIterable)
provides(IXMLExport)
def __init__(self, frobnariterator):
self.frobnars = frobnariterator
def export(self):
entries = []
for frobnar in self.frobnars:
entries.append(
u'<frobnar><width>{0}</width><height>{0}</height></frobnar>'.format(
frobnar.width, frobnar.height)
return u''.join(entries)
コードは、各形状のアダプターを検索するだけです。
for obj in setofobjects:
self.result.append(IXMLExport(obj).export())