Существует ли потребность в “использовании строгий” компилятор Python?

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

Например, в Parglare (раскрытие: я автор) это будет что-то вроде:

from parglare import Grammar, Parser

grammar = r'''
S: E EOF;
E: Term | And | Not | Or | To | Parent;
And: left=E 'AND' right=E;
Or: left=E 'OR' right=E;
Not: 'NOT' val=E;
To: from=E 'TO' to=BASETYPE;
Parent: '(' E ')' {9};
Term: name=ID TermOp value=BASETYPE {10};
TermOp: ':' | '=' | '>' | '<' | '<=' | '>=';
BASETYPE: NUM | STRING | ID;

terminals
NUM: /\d+(\.\d+)?/;
ID: /[a-zA-Z_][_a-zA-Z0-9]*/;
STRING: /("(\\"|[^"])*")|(\'(\\\'|[^\'])*\')/;
'''

g = Grammar.from_string(grammar)
parser = Parser(g)

out = parser.parse(r'''
available = 1 AND (category:Book OR NOT category:Ebook)
     AND _tags:published
     AND publication_date:1441745506 TO 1441755506
     AND inStock > 0 AND author:"John Doe"
''')

out ссылка в конце будет хорошим объектом Модель выведена из грамматики выше. Вы можете исследовать это в отладчике, чтобы почувствовать. Я не охватил весь язык, так как не знаю, но вы поняли.

Теперь было бы относительно легко расширить этот пример для поддержки полного языка и сделать отображение данной структуры для запроса.

Было бы еще проще, если бы вы использовали parglare действия для непосредственного преобразования анализируемого ввода в желаемый вывод. Вы можете прочитать больше об этом в документах .

30
задан Community 23 May 2017 в 12:09
поделиться

9 ответов

"время выполнения обязательная философия, которую Python охватывает..., "использует строгое" ненужное поведение [и] особенно нежелательное"

Довольно хорошая сводка. Спасибо.

, Который является по существу этим. Инструменты статического анализа не помогают Python достаточно стоить.

<час>

Редактирование

"я прошу нас заниматься самоанализом на [1 112], почему нам не нужно оно и, связано, почему программисты Perl думают, что им действительно нужно оно".

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

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

я пишу Java почти так, как я пишу Python. Статическая проверка типа Java не предотвращает логических проблем; это не упрощает встречающиеся требования к производительности; это не помогает встретить варианты использования. Это даже не уменьшает объем поблочного тестирования.

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

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

Взгляд, самое большее популярный ТАК вопросы о Python, которые являются языком (не проблемная область или библиотека) связанный.

там любое различие между " нечто является None" и " нечто == None"? - == по сравнению с is. Никакая статическая проверка не может помочь с этим. Кроме того, см. там различие между '==' и 'находится' в Python?

, Что делает ** (удваивают звезду) и * (звезда) делают для параметров? - *x дает список, **x дает словарь. Если Вы не знаете это, Ваша программа умирает сразу, когда Вы пытаетесь сделать что-то несоответствующее для тех типов. "Что, если Ваша программа никогда не делает ничего 'несоответствующего'". Тогда Ваши работы программы. 'nuff сказан.

, Как может, я представляю ' Enum' в Python? - это - просьба о некотором ограничено-доменном типе. Класс со значениями уровня класса в значительной степени делает то задание. "Что, если кто-то изменяет присвоение". Легкий создать. Переопределение __set__ для повышения исключения. Да статическая проверка могла бы определить это. Нет, этого не происходит на практике, что кто-то запутывается о перечислимой константе и переменной; и когда они делают, легко определить во время выполнения. "Что, если логика никогда не выполняется". Ну, это - плохой дизайн и плохое поблочное тестирование. Бросок ошибки компилятора и включение неправильной логики, это никогда не тестируется, не лучше, чем, что происходит на динамическом языке, когда это никогда не тестируется.

Выражения Генератора по сравнению с Пониманием Списка - статическая проверка не помогает разрешить этот вопрос.

, Почему делает 1 +++ 2 = 3? - статическая проверка не определила бы это. 1 +++ 2 в C совершенно законен несмотря на всю проверку компилятора. Это не то же самое в Python, как это находится в C, но столь же законный. И так же, как сбивающий с толку.

Список изменений списков, отраженных через подсписки неожиданно - Это совершенно концептуально. Статическая проверка не может помочь решить эту проблему также. Эквивалентный Java также скомпилировал бы и вел бы себя плохо.

12
ответ дан Community 27 November 2019 в 23:24
поделиться

У меня нет фона Perl, но от того, что я знаю, нет никакой функции в Python, который должен быть отключен для Вашего кода, чтобы быть "более надежным", так в этом смысле, я предполагаю, что можно сказать, что это ненужное

-3
ответ дан John T 27 November 2019 в 23:24
поделиться

Это походит на идеал подач кода "Pythonic" большая та же цель как use strict.

-2
ответ дан Hank Gay 27 November 2019 в 23:24
поделиться

Я нашел, что только действительно забочусь об обнаружении ссылок на необъявленный Вар. Eclipse имеет pylint интеграцию через PyDev и, хотя pylint совсем не прекрасен, это делает разумное задание в этом.

Это действительно отчасти идет вразрез с динамическим характером Python, и я действительно должен добавлять #IGNOREs иногда, когда мой код становится умным о чем-то. Но я нахожу, что это происходит нечасто достаточно, что я доволен им.

, Но я видел утилиту некоторой подобной pylint функциональности, становящейся доступным в форме флага командной строки. Отчасти как переключатель Python 2.6's-3, который определяет точки несовместимости между кодом Python 2.x и 3.x.

1
ответ дан DNS 27 November 2019 в 23:24
поделиться

Я рассматриваю 'use strict' в Perl больше как прагма, когда Вы намекнули: это изменяет поведение компилятора.

философия языка Perl отличается от философии Python. Как в, Вам дают более чем достаточно веревки для зависания себя неоднократно в Perl.

Larry Wall является крупным в лингвистику, таким образом, мы имеем от Perl, что упоминается как TIMTOWTDI (скажите tim-toe-dee), принцип по сравнению с Дзэн Python:

должны быть один - и предпочтительно только один - очевидный способ сделать это.

Вы могли очень легко использовать pylint и PyChecker для предложения собственной разновидности use strict для Python (или что-то аналогичное perl -cw *scriptname*), но из-за различных основных положений в дизайне языка, Вы не встретитесь с этим на практике широко.

На основе Вашего комментария к первому плакату, Вы знакомы с Python import this. Существует много вещей там, которые освещают, почему Вы не видите эквивалент use strict в Python. Если Вы размышляете на koan, найденный в Дзэн Python, можно найти просвещение для себя.:)

3
ответ дан popcnt 27 November 2019 в 23:24
поделиться

Python действительно имеет что-то, что может изменить синтаксис сценария:

from __future__ import print_function

и различные другие будущие функции, которые имеют последствия синтаксиса. Это просто, что синтаксис Python был более строгим, более стабильным и более четко определенным, чем исторический Perl; вид вещей, которые запрещают ‘strict refs’ и ‘strict subs’, никогда не существовал в Python.

‘strict vars’, прежде всего, предназначен для остановки typoed ссылок и пропущен ‘my’s в создании случайного globals (хорошо, переменные пакета в терминах Perl). Этого не может произойти в Python как пустое значение по умолчанию присвоений к локальному объявлению и пустой неприсвоенный результат символов в исключении.

(Там все еще имеет место, где пользователи случайно пытаются записать - до глобального, не объявляя это с оператором ‘global’, вызывая или локальный случайный элемент или, чаще, UnboundLocalError. Это имеет тенденцию быть изученным справедливо быстро, но это - спорный случай, где необходимость объявить Ваших местных жителей могла помочь. Хотя немного опытных Python программистов приняли бы нагрузку удобочитаемости.)

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

11
ответ дан bobince 27 November 2019 в 23:24
поделиться

Ну, я не большая часть программиста Python, но я сказала бы, что ответ - 'ДА'.

Любой динамический язык, который позволяет Вам создать переменную с любым именем в любое время, мог использовать 'строгую' прагму.

Строгий Вар (одна из опций для строгого в Perl, 'используют строгий', поворачивает их всех на сразу) в Perl требует, чтобы все переменные были объявлены, прежде чем они будут использоваться. Что означает что этот код:

my $strict_is_good = 'foo';
$strict_iS_good .= 'COMPILE TIME FATAL ERROR';

Генерирует фатальную ошибку во время компиляции.

я не знаю о способе заставить Python отклонять этот код во время компиляции:

strict_is_good = 'foo';
strict_iS_good += 'RUN TIME FATAL ERROR';

Вы получите исключение на этапе выполнения, которое strict_iS_good не определено. Но только когда код выполнен. Если Ваш набор тестов не имеет 100%-го покрытия, можно легко поставить эту ошибку.

Любое время я работаю на языке, который не имеет этого поведения (PHP, например), я становлюсь возбужденным. Я не идеальная машинистка. Простое, но трудно определить, опечатка может заставить Ваш код перестать работать способами, которые может быть трудно разыскать.

Так, для повторения ДА Python мог использовать 'строгую' прагму для включения проверок времени компиляции на вещи, которые могут быть проверены во время компиляции. Я не могу думать ни о каких других проверках для добавления, но лучший Python программист, вероятно, мог думать о некоторых.

Примечание я фокусируюсь на прагматическом эффекте stict Вара в Perl, и заминаю некоторые детали. Если Вы действительно хотите знать, что все подробности видят perldoc для строгого .

Обновление: Ответы на некоторые комментарии

Jason Baker : Статические средства проверки как pylint полезны. Но они представляют дополнительный шаг, который может быть и часто пропускается. Встраивание некоторых основных проверок в компилятор гарантирует, что эти проверки последовательно выполняются. Если эти проверки управляемы прагмой, даже возражение, касающееся стоимости проверок, становится спорным.

popcnt: Я знаю, что Python генерирует исключение времени выполнения. Я сказал так же. Я защищаю время компиляции, проверяя, если это возможно. Перечитайте сообщение.

mpeters: Никакой компьютерный анализ кода не может найти все ошибки - это составляет решение проблемы остановки. Хуже, для нахождения опечаток в присвоениях компилятор должен был бы знать Ваш намерения и найти места, где намерения отличаются от кода. Это довольно явно невозможно.

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

я не достаточно знаком с pylint и pychecker для высказывания, какие классы ошибок они поймают. Как я сказал, я очень неопытен с Python.

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

Обновление 2:

cdleary - В теории, я соглашаюсь с Вами, статический анализатор может сделать любую проверку, что компилятор может. И в случае Python, это должно быть достаточно.

Однако, если Ваш компилятор достаточно сложен (особенно, если у Вас есть много прагм, которые изменяются, как компиляция происходит, или если как Perl, можно выполнить код во время компиляции), тогда статический анализатор должен приблизиться к сложности компилятора/интерпретатора, чтобы сделать анализ.

Heh, весь этот разговор о сложных компиляторах и выполняющий код во время компиляции показывает мое образование Perl.

Мое понимание - то, что Python не имеет прагм и не может выполнить произвольный код во время компиляции. Так, если я не ошибаюсь, или эти опции добавляются, относительно простой синтаксический анализатор в статическом анализаторе должен быть достаточным. Конечно, было бы полезно вызвать эти проверки при каждом выполнении. Конечно, способ, которым я сделал бы это, с прагмой.

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

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

(Никоим образом не намереваются подвергнуть сомнению поддержку Python, когда я говорю, что это не может, futz с поведением времени компиляции как Perl может. У меня есть догадка, что это - тщательно продуманное проектное решение, и я вижу мудрость в нем. Экстремальная гибкость Perl во время компиляции является, по моему скромному мнению, большой силой и ужасной слабостью языка; я вижу мудрость в этом подходе также.)

35
ответ дан John T 27 November 2019 в 23:24
поделиться

Python не имеет никакого истинного лексического обзора, таким образом, строгий Вар не был бы очень разумен. Это не имеет никаких символьных ссылок AFAIK, таким образом, это не имеет потребности в строгих судьях. Это не имеет barewords, таким образом, это не имеет никакой потребности в строгом Варе.

Честно говоря, это - только лексический обзор, который я пропускаю. Другие два я рассмотрел бы бородавки в Perl.

5
ответ дан Leon Timmermans 27 November 2019 в 23:24
поделиться

Я думаю, что существует некоторый беспорядок как, что "использование, строгое", делает из комментариев, которые я вижу. Это не включает проверки типа времени компиляции (чтобы быть похожим на Java). В этом смысле пробабушки Perl в согласии с программистами Python. Как S.Lott говорит выше этих типов проверок, не защищают от логических ошибок, не сокращайте количество модульных тестов, которые необходимо записать, и мы - также не большие поклонники программирования неволи.

Вот список того, что "действительно делает использование, строгое":

  1. Используя символьные ссылки ошибка времени выполнения. Это препятствует тому, чтобы Вы делали сумасшедший (но иногда полезные вещи как)

    $var = 'foo';

    $foo = 'bar';

    print $$var; # this would contain the contents of $foo unless run under strict

  2. Используя необъявленные переменные ошибка времени выполнения (это означает, что необходимо использовать "мой", "наш" или "локальный" для объявления объема переменной перед использованием ее.

  3. Все barewords считают синтаксическими ошибками времени компиляции. Barewords являются словами, которые не были объявлены как символы или подпрограммы. Это должно главным образом запретить что-то, что исторически сделали, но, как полагают, было ошибкой.

7
ответ дан mpeters 27 November 2019 в 23:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: