2016-01-17 12 views
12

Das neue Modul typing enthält mehrere Objekte mit Namen wie "SupportsInt" (-Float, -Bytes, etc.). Der Name und die Beschreibungen unter the documentation page for the module könnten gelesen werden, um darauf hinzuweisen, dass Sie testen können, ob ein Objekt von einem Typ ist, der "__int__() unterstützt". Aber wenn Sie versuchen, isinstance() zu verwenden, ist es eine Antwort gibt, die deutlich macht, dass das ist nicht etwas, was Sie tun sollen:"Protokolle können nicht mit isinstance()" verwendet werden - warum nicht?

>>> isinstance(5, typing.SupportsInt) 
(Traceback omitted) 
TypeError: Protocols cannot be used with isinstance(). 

Auf der anderen Seite können Sie issubclass() verwenden:

>>> issubclass((5).__class__, typing.SupportsInt) 
True 
>>> issubclass(type(5), typing.SupportsInt) 
True 

Was ist ein "Protokoll" in diesem Zusammenhang? Warum verbietet es auf diese Weise die Verwendung von isinstance()?

+1

Der Zweck des Moduls 'typing' ist ** nicht **, um eine Möglichkeit zur Durchführung dieser Prüfungen zu bieten. Es soll eine allgemeine Möglichkeit bieten, um die Arten von Funktionen usw. in ihren Anmerkungen bereitzustellen. Duck-Typisierung wird immer noch bevorzugt. Sie können diese Typen verwenden, um Ihrem Benutzer mitzuteilen, wie die Funktion aufgerufen werden soll. – Bakuriu

+0

@Bakuriu, aber das Typisierungsmodul wird teilweise zur Verfügung gestellt, um eine statische Typprüfung zu erlauben, und daher ist es vernünftig anzunehmen, dass es die Maschinerie zum Identifizieren (sagen wir), ob ein bestimmtes Objekt von einem bestimmten Typ ist, bereitstellen wird. Wenn ich eine Funktion aufrufen, die 5 als einen Parameter mit dem Typ typing.SupportsInt übergibt, wie weiß dann ein statischer Typüberprüfer, dass dieser gültig ist? – Hammerite

Antwort

1

Das alles der Argumentation in PEP 484, der PEP für das typing Modul gegeben ist:

Da typing.Callable double-duty tut als Ersatz für collections.abc.Callable, isinstance (x, typing.Callable) wird implementiert, indem auf 'isinstance (x, collections.abc.Callable) verschoben wird. Isinstance (x, typing.Callable [...]) wird jedoch nicht unterstützt.

Ein Protokoll ist auch als magic method bekannt. Dies sind die meisten der Python-Protokolle (vollständige Liste here):

>>> dir(object) 
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', 
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', 
'__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 

ich keinen klaren Grund gefunden, warum typing nicht isinstance unterstützen. Der Grund dafür, dass issubclass funktioniert, ist, dass isinstance das Protokoll __class_ verwendet, das in typing nicht zulässig ist, während issubclass das Protokoll __subclasshook__ verwendet, das zulässig ist. Ich glaube der Grund ist, dass die Funktionalität bereits in collections.abc.Callable kodiert wurde und sie nicht im typing Modul umcodieren wollten.

Verwandte Themen