2016-11-20 1 views
0

Я часто нахожу, что я пишу выражения с несколькими операторами, чтобы проверять типы переменных во время выполнения. Например, предположим, что я хотел, чтобы убедиться, что конкретный вход список объектов Foo, я мог бы написать следующее выражение:Есть ли способ определить, является ли объект «экземпляром» выражения стиля pep484 во время выполнения?

assert(_isinstance(x, list) and all(_isinstance(y, Foo) for y in x)) 

я лучше быть в состоянии написать что-то вроде:

# pseudocode 
_assert(isinstance(x, typing.List[Foo])) 

Другими словами, я хочу задать x список экземпляров Foo.

Если это может быть сделано для работы, это было бы лучше, потому что синтаксис Pep484 - отличный способ кратко указать типы вложенных структур. Конечно, мы все знаем, что это не так, как работает встроенная функция Python isinstance ... но мне просто снится на мгновение:

Мы все знакомы с функцией isnstance, которая возвращает True, если внешний тип структуры является экземпляром класса:

# real python: 
isinstance(["a", "b", "c"], list) => True 

Но предположим, что я хочу сделать более глубокие проверки: Я хотел бы сделать что-то вроде:

# pseudocode: 
import typing 
_isinstance("x", str) => True 
_isinstance(["a", "b", "c"], typing.List[str]) => True 
_isinstance(["a", "b", "c"], typing.List[float]) => False 
_isinstance([{"x":3}], typing.List[typing.Map[str,int]]) => True 

Так идея заключается в том, что функция вернет True, если 1-й аргумент полностью соответствует стилю стиля Pep484 второго аргумента.

Конечно, некоторые из вас укажут, что явная статическая проверка и проверка времени выполнения противоречат духу «утиной печати». Это правда, но не полезно. Иногда вы действительно хотите проверить структуру ввода. По мере того, как проекты становятся все больше, вы иногда хотите узнать наверняка, с какими типами вы сталкиваетесь, и в другое время вам нужна гибкость, которую дает вам утка.

Итак, вот мой вопрос: кто-нибудь видел способ сравнить выражения стиля Pep484 с типами? Если для этого уже есть библиотека или функция, я бы предпочел не изобретать колесо. Возможно, у библиотеки ввода есть способ сделать это. Назовите меня, пожалуйста!

+0

Вы использовали 'isinstance' назад во всех своих гипотетических примерах. Не то, чтобы это сработало, если бы вы перевернули его. 'isinstance' не делает то, что вы хотите. – ShadowRanger

+0

Это было обратное в одном примере - я исправил это, спасибо! –

+0

Вы только что сделали это назад в другом примере. Прототипом является 'isinstance (obj, type_or_tuple_of_types)', а не 'isinstance (type_or_tuple_of_types, obj)'. Тестирование, если 'x' имеет тип или подтип' list', является 'isinstance (x, list)', а не 'isinstance (list, x)'. – ShadowRanger

ответ

-1

Вы могли бы сделать это следующим образом:

def _isinstance(var, type): 
    if not isinstance(var, type): 
     return False 

    if isinstance(var, Iterable) and not isinstance(var, Generator): 
     return all(any(isinstance(v, t) for t in type.__parameters__) for v in var) 

    return True 

Конечно, это не так уж сильно отличается от того, что у вас уже есть, но это дает «простота» делает assert(isinstance(x, List[Foo])). Здесь x должен быть итерируемым.

Обратите внимание, что невозможно определить типы данных, которые генератор будет производить без повторения через него, тем самым потеряв все эти данные.

Python is утка-типизированная и не заботится о типах много. Если что-то крякает, как утка, то это утка для Питона.

+0

Привет, говоря, что «Python утилит и не заботится о типах много» не особенно полезен. Иногда вам действительно нужно проверять типы (например, на границах интерфейса). В другое время мы можем немного расслабиться и доверять утиной печати. Я согласен с тем, что в случае одноразовых обходных структур (например, генераторов) вы не смогли проверить входные данные без рендеринга объекта, но это правда, однако вы хотите проверить свои типы! –

+0

@SalimFadhley, ну, это правда ... Если вы обнаружите, что вам нужно проверять типы в Python, вы можете делать что-то не так и, возможно, захотите перейти на какой-то строго типизированный язык, хотя в C++ для Например, проверка типа явно (с условием 'if', например) считается плохой практикой, насколько мне известно. – ForceBru

+0

Мне любопытно, почему вы считаете, что это неподходящий вопрос: Python 3.5.x явно указывает на мини-язык с целью указания типов (для типа-намека), мой вопрос заключается в том, есть ли способ использовать эти те же выражения для проверки типов во время выполнения. Это не то, что нужно каждому проекту, но что-то, что будет очень полезно в моем случае. Это старый проект с довольно большим количеством структурированных данных. –

Смежные вопросы