Как я могу убедиться, что весь мой код Python "компилируется"?

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

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

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

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

Ответы

Ответ 1

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

Здесь пример вывода из pylint, возникающий из тривиальной программы:

print a

Как вы можете видеть, он обнаруживает переменную undefined, которую 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: "))

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()

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

foo = 5
print food

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

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

Ответ 5

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