Как я могу убедиться, что весь мой код Python "компилируется"? - PullRequest
14 голосов
/ 22 июня 2009

Мой фон - C и C ++. Мне очень нравится Python, но есть один его аспект (и другие интерпретируемые языки, я думаю), с которым действительно трудно работать, когда вы привыкли к скомпилированным языкам.

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

Очевидно, что система должна быть достаточно протестирована, чтобы убедиться, что весь код запущен, но большую часть времени я использую Python для собственных сценариев и небольших инструментов, что, разумеется, никогда не привлекает внимания QA, в котором они нуждаются. Кроме того, некоторый код настолько прост, что (если вы работали с C / C ++), вы знаете, что он будет хорошо работать до тех пор, пока он компилируется (например, методы getter внутри классов, обычно это простой возврат переменной-члена).

Итак, мой вопрос очевиден - есть ли способ (с помощью специального инструмента или чего-то еще), чтобы я мог убедиться, что весь код в моем скрипте Python будет «компилироваться» и запускаться?

Ответы [ 5 ]

21 голосов
/ 22 июня 2009

Посмотрите на PyChecker и PyLint .

Вот пример вывода из pylint, полученного из тривиальной программы:

print a

Как видите, он обнаруживает неопределенную переменную, которую py_compile не будет (намеренно).

in foo.py:

************* Module foo
C:  1: Black listed name "foo"
C:  1: Missing docstring
E:  1: Undefined variable 'a'


...

|error      |1      |1        |=          |

Тривиальный пример того, почему тесты недостаточно хороши, даже если они охватывают «каждую строку»:

bar = "Foo"
foo = "Bar"
def baz(X):
    return bar if X else fo0

print baz(input("True or False: "))

РЕДАКТИРОВАТЬ: PyChecker обрабатывает троичный для меня:

Processing ternary...
True or False: True
Foo

Warnings...

ternary.py:6: No global (fo0) found
ternary.py:8: Using input() is a security problem, consider using raw_input()
2 голосов
/ 30 июня 2009

Другие упоминали о таких инструментах, как PyLint, которые довольно хороши, но, в общем и целом, это просто невозможно сделать 100%. На самом деле, вы можете даже не захотеть это делать. Одним из преимуществ динамичности Python является то, что вы можете делать сумасшедшие вещи, такие как вставка имен в локальную область посредством доступа к словарю.

Суть в том, что если вам нужен способ отлавливать ошибки типов во время компиляции, вы не должны использовать Python. Выбор языка всегда подразумевает множество компромиссов. Если вы выбираете Python вместо C, просто имейте в виду, что вы торгуете системой сильных типов для более быстрой разработки, лучшей обработки строк и т. Д.

1 голос
/ 22 июня 2009

Если вы используете Eclipse с Pydev в качестве IDE, он может пометить много опечаток для вас красными волнистыми буквами, а также имеет интеграцию с Pylint. Например:

foo = 5
print food

будет помечено как «Неопределенная переменная: еда». Конечно, это не всегда точно (возможно, еда была определена ранее с использованием setattr или других экзотических методов), но в большинстве случаев она работает хорошо.

В общем, вы можете статически анализировать ваш код только в той степени, в которой он действительно статичен; чем динамичнее ваш код, тем больше вам действительно нужно автоматизированное тестирование.

1 голос
/ 22 июня 2009

Я думаю, что вы ищете, это покрытие строки кода теста. Вы хотите добавить тесты в ваш скрипт, которые будут проверять все ваши строки кода или столько, сколько у вас есть время. Тестирование - это большая работа, но если вам нужна гарантия, которую вы запрашиваете, бесплатного обеда нет, извините :(.

0 голосов
/ 22 июня 2009

Ваш код на самом деле компилируется, когда вы его запускаете, среда выполнения Python будет жаловаться, если в коде есть синтаксическая ошибка. По сравнению со статически скомпилированными языками, такими как C / C ++ или Java, он не проверяет правильность имен и типов переменных - для этого вам действительно нужно запустить код (например, с помощью автоматических тестов).

...