2013-04-18 2 views
4

Python не проверяет типы во время компиляции, потому что он не может, по крайней мере, в некоторых случаях. Но кто-нибудь придумал механизм для проверки типа компиляции, основанный на дополнительных аннотациях пользователя? Что-то вроде pylint, который автор использует дополнительные гарантии? Я имею в виду что-то вроде:Проверка типа времени компиляции Python

#guarantee(argument=int, return_type=int) 
def f(x): 
    return x + 3 

#guarantee(argument=int, return_type=str) 
def g(x): 
    return "%d times" % x 

y = f(6) 

# works, z = "9 times" 
z = g(y) 
# error 
a = f(z) 

Эта шашка будет интерпретировать комментарии выше каждой функции, понимают, что f(x) только должен принять int но г приходит из g(x) так это str. Есть ли какой-нибудь продукт, который делает что-то похожее на это?

+1

Мое понимание PyPy действительно похоже на это, но, как правило, люди не пытаются использовать не-Python Python, они просто используют строго типизированный язык. Кроме того, в Python в действительности нет такой вещи, как «время компиляции». Вы можете иметь статический или динамический анализ кода, а преобразование в pyc можно рассматривать как компиляцию, но на фундаментальном уровне произвольный код может изменить что-либо о системе во время выполнения. –

ответ

2

PEP 3107 был недавно завершен (недавно был когда-то в прошлом году), который вводит аннотации к переменным и функциям. К сожалению (как вы можете видеть из числа pep), это применимо только к Python 3.x, поэтому любая контрольная сумма (или даже код), которую вы пишете, чтобы использовать ее, будет только Python 3 (что действительно не плохо).

Вы упомянули pylint, поэтому я предполагаю, что вы фактически не хотите, чтобы проверки выполнялись во время компиляции, но вместо этого проверялись после компиляции. Это было бы замечательным инструментом для обсуждения на code-quality mailing list.

+0

Это именно то, что я искал, спасибо! – noisecapella

+0

@noisecapella рада помочь –

0

Я не уверен, как это значительное улучшение по сравнению с существующими механизмами времени выполнения в Python. Например,

def f(x): 
    if not isinstance(x, int): 
     raise TypeError("Expected integer") 
    return x + 3 

def g(x): 
    return "%d times" % x 

# Works. 
y = f(6) 
z = g(y) 
# Fails, raises TypeError. 
a = f(z) 

Иными словами, без аннотирования каждой функции и каждый метод каждого объекта в Python, было бы трудно статически определить именно то, что тип возвращаемого значения либо f или g есть. Я сомневаюсь, что любая статическая проверка по этим линиям будет иметь какую-то ценность.

Даже если вы добавили дескрипторы возвращаемого типа к своим функциям, действительно ли это гарантия? Это похоже на документацию, которая может не обновляться вместе с кодом, что приведет к еще более коварным ошибкам, вызванным неправильными предположениями позже.

+2

А как насчет объектов, которые ведут себя как другие типы при их трактовке как таковых (через '__str__',' __nonzero__' и т. П.)? Python находится на базовом уровне, утином; любая попытка навязать статическую типизацию либо терпит неудачу, либо сломает язык. –

+0

Тег 'static-analysis' подразумевает, что это не предназначено для навязывания во время выполнения. –

+0

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

1

Я думаю, что ваше недостающее ключевое слово decorator.

Вы можете написать свои собственные декораторы делать такие вещи, как:

@check(bar=int) 
foo(bar): 
    pass 

Вы можете увидеть пример реализации here. Хотя это, конечно, не подходит для проверки компиляции, поскольку это выполняется во время выполнения.

+0

Да, я реализовал такую ​​вещь один раз. Одна из менее интересных проблем при внедрении этих декораторов делает IDE осведомленной о том, что вы сделали, и поэтому предложения кода могут быть испорчены - не знаю, если они сделали это в вашем примере.EDIT: neah, это проблема, если вы просто проходите * args и ** kwargs, предложение кода теряется в переводе: P –

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