2009-06-22 8 views
14

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

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

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

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

+0

Прекрасный ... Я парень C/C++, новый для Python, и эта проблема разочаровала меня до конца. Я никогда не думал спрашивать о решении, хотя, я не думал, что он может существовать. –

ответ

21

Посмотрите на 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  |=   | 
. 10

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

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

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

EDIT: 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() 
+1

Хорошая рекомендация pychcker и pylint. pyflakes также хорош, потому что он очень быстрый, и версия svn trunk будет ловить неиспользуемые локальные переменные. Что касается тестирования «каждой строки», я думаю, вы должны хотя бы проверить каждый «путь». Это поймало бы ваш пример взрыва. –

+1

Отлично работает Мэтью, спасибо! – sharkin

+0

Невозможно определить (а затем проверить) все возможные логические пути, поскольку это эквивалентно проблеме остановки (http://en.wikipedia.org/wiki/Code_coverage). –

1

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

+1

Он не ищет код для прохождения тестов. Он уже сказал: «Через 6 месяцев, когда в противном случае хороший код, наконец, запущен, он может просто разорваться из-за некоторой опечатки». Тесты проверяют, действительно ли код делает «правильную вещь» для некоторого конечного набора входных данных, а не использует ли он действительный синтаксис (что хочет OP) –

+1

Он не пройдет много тестов, если у него есть опечатки. Если ваше покрытие затрагивает каждую строку кода (не каждый логический путь), вы будете уверены, что он будет работать надежно. –

+0

-1. Мне жаль Адама, вопрос предполагает, что такие усилия по обеспечению качества являются довольно нереалистичными, поэтому ответ мало помогает. – sharkin

0

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

+1

-1. Кажется, на самом деле существуют инструменты для обнаружения таких ошибок, поэтому не нужно фактически запускать код, чтобы обнаружить их. – sharkin

1

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

foo = 5 
print food 

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

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

2

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

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

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