Вопрос:

Python: рекурсивная проверка isinstance

python python-3.x oop python-3.5 type-hinting

392 просмотра

1 ответ

6702 Репутация автора

Как проверить полную сигнатуру типа вложенного абстрактного класса? В этом примере

In [4]: from typing import Sequence

In [5]: IntSeq = Sequence[int]

In [6]: isinstance([1], IntSeq)
Out[6]: True

In [7]: isinstance([1.0], IntSeq)
Out[7]: True

Я хочу, чтобы последний isinstanceвызов действительно возвращался False, пока он только проверяет, является ли аргумент a Sequence. Я думал о рекурсивной проверке типов, но IntSeqне имеет открытых атрибутов, которые хранят вложенные типы:

In [8]: dir(IntSeq)
Out[8]: 
['__abstractmethods__',
 '__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__extra__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__len__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__origin__',
 '__parameters__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__slots__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 '_abc_cache',
 '_abc_negative_cache',
 '_abc_negative_cache_version',
 '_abc_registry']

Так что не так просто получить вложенные типы. Я не могу найти соответствующую информацию в документах.

PS Мне это нужно для многократной реализации.

Обновить

Благодаря отзывам Александра Хуссага и Блендера мы теперь знаем, что у абстрактных классов в Python 3.5 (может) есть два атрибута, которые хранят вложенные типы: __parameters__и __args__. Первый существует под Linux (Ubuntu) и Darwin (OS X), хотя в случае с Linux он пуст. Последний доступен только в Linux и хранит типы, как __parameters__в OS X. Эти детали реализации дополняют путаницу.

Автор: Eli Korvigo Источник Размещён: 22.08.2016 09:06

Ответы (1)


2 плюса

89519 Репутация автора

Решение

Я вижу, вы пытаетесь реализовать что-то, используя модуль, который все еще временно; вы обязательно столкнетесь с изменяющимся интерфейсом, если вы сделаете это.

Блендер заметил, что __parameters__аргумент содержит параметры для типа; это было правдой, пока, я полагаю 3.5.1. В моем git-клоне самой последней версии Python ( 3.6.0a4+) __parameters__снова содержится пустой кортеж, __args__аргумент и __origin__первая запись в его __bases__атрибуте:

>>> intSeq = typing.Sequence[int]
>>> intSeq.__args__
(<class 'int'>,)
>>> intSeq.__parameters__
()
>>> intSeq.__origin__
typing.Sequence<+T_co>

Поскольку 3.6при выводе, из того, что я понимаю PEP 411, вводится временное состояние и происходит переход в стабильное состояние, именно с этой версией вы должны работать, чтобы реализовать свои функциональные возможности.

Автор: Jim Fasarakis Hilliard Размещён: 23.08.2016 10:04
Вопросы из категории :
32x32