Подтвердить что ты не робот

У python есть "использование строгого"; и "использовать предупреждения"; как в perl?

Я изучаю perl и python... в то же время, а не по дизайну, но это нужно сделать.

Вопрос:

В perl script я использую (см. ниже) во главе моего txt.

#!/usr/bin/env perl

use strict;
use warnings;

Есть ли что-то, что я должен делать в рутине для моих сценариев python?

4b9b3361

Ответ 1

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

Две прагматы в вашем исходном вопросе действительно расширяются до:

use strict "vars";
use strict "refs";
use strict "subs";
use warnings;

Чтобы ответить каждому по очереди:

  • Эффект use strict "vars" заключается в том, чтобы вызвать ошибку времени компиляции для ссылки на переменную без предварительного объявления, что она существует (например, по умолчанию используется более статичные языки, такие как C, С++ и Java). Поскольку Python не имеет определенного синтаксиса для объявления переменной, она не имеет эквивалента. Присвоение имени в Python всегда создает его, если оно не было вначале. Эта функция strict не имеет эквивалента Python, и ее безопасность не может быть воссоздана.

Например:

$ perl -c -e 'use strict "vars"; $foo = 1'
Global symbol "$foo" requires explicit package name at -e line 1.
-e had compilation errors.

$ perl -c -e 'no strict "vars"; $foo = 1'
-e syntax OK
  • Эффект use strict "refs" заключается в том, чтобы запретить использование простых строк, содержащих имя (существующей или новой) переменной, в качестве ссылки на самую переменную. Python этого не делает, поэтому нет необходимости отключать его.

Например:

$ perl -e 'use strict "refs"; ${"message"} = "hello"; print $message'
Can't use string ("message") as a SCALAR ref while "strict refs" in use at -e line 1.

$ perl -e 'no strict "refs"; ${"message"} = "hello"; print $message'
hello
  • Эффект use strict "subs" заключается в том, чтобы заставить компиляцию использовать любую попытку вызова функции, которая, как известно, не существует. Python не выполняет такую ​​проверку и не имеет возможности включить такую ​​функцию.

Например:

$ perl -c -e 'use strict "subs"; foo'
Bareword "foo" not allowed while "strict subs" in use at -e line 1.
-e had compilation errors.

$ perl -c -e 'no strict "subs"; foo'
-e syntax OK
  • Эффект use warnings заключается в том, чтобы разрешить больше предупреждений как при компиляции, так и во время выполнения различных категорий поведения, которые были по умолчанию в более ранних версиях, иногда может быть желательным или никогда не было хорошей идеей, но не является строго ошибка. Например, использование неинициализированных значений как чисел обычно должно давать предупреждение, но изначально оно этого не делало.

Например:

$ perl -e 'use warnings; my $u; print 2 + $u'
Use of uninitialized value $u in addition (+) at -e line 1.
2

$ perl -e 'no warnings; my $u; print 2 + $u'
2

Наконец; было сделано несколько замечаний о том, что Python имеет аналогичную функциональность в __future__. Однако это не следует считать похожим на Perl pragmata, так как большинство из них лексически охвачены и могут быть включены или отключены в небольших областях по мере необходимости; где Python __future__ включен только для всего исходного файла.

Eg.

use strict;
use warnings;

my $total;

$total += count_things($_) for @list;

{
   no warnings 'uninitialized';
   printf "The total is %d\n", $total;
}

Несколько надуманный пример, но этот демонстрирует использование no warnings 'uninitialized', чтобы отключить предупреждение об использовании неинициализированного значения просто в инструкции printf, сохраняя при этом другие предупреждения в других местах.


В заключение: Python не имеет use strict или любого почти эквивалентного, поскольку любая из функций безопасности, которые он предоставляет, либо обязательна, либо недоступна на языке Python и не имеет use warnings. Те функции, которые он предоставляет, разрешены только на уровне файлов и не могут быть выборочно включены или отключены для каждой области.


Изменить: На самом деле мне сообщили, что Python имеет некоторые управляемые предупреждающие флаги, которые могут быть включены и отключены по мере необходимости.

Ответ 2

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

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

def Main():
    print(GetPrice(100,"Alaska"))
    print(GetPrice(100,"Florida"))
    print(GetPrice(100,"Michigan"))
    print(GetPrice(100,"Wisconsin"))

def GetPrice(UnitPrice,State):
    StateSalesTaxRate = 0
    if State == "Alabama": StateSalesTaxRate = 0.04
    if State == "Alaska": StateSalesTaxRate = 0
    if State == "Arizona": StateSalesTaxRate = 0.056
    if State == "Arkansas": StateSalesTaxRate = 0.065
    if State == "California": StateSalesTaxRate = 0.075
    if State == "Colorado": StateSalesTaxRate = 0.029
    if State == "Connecticut": StateSalesTaxRate = 0.0635
    if State == "Delaware": StateSalesTaxRate = 0
    if State == "Florida": StateSalesTaxRate = 0.06
    if State == "Georgia": StateSalesTaxRate = 0.04
    if State == "Guam": StateSalesTaxRate = 0.04
    if State == "Hawaii": StateSalesTaxRate = 0.04
    if State == "Idaho": StateSalesTaxRate = 0.06
    if State == "Illinois": StateSalesTaxRate = 0.0625
    if State == "Indiana": StateSalesTaxRate = 0.07
    if State == "Iowa": StateSalesTaxRate = 0.06
    if State == "Kansas": StateSalesTaxRate = 0.0615
    if State == "Kentucky": StateSalesTaxRate = 0.06
    if State == "Louisiana": StateSalesTaxRate = 0.04
    if State == "Maine": StateSalesTaxRate = 0.055
    if State == "Maryland": StateSalesTaxRate = 0.06
    if State == "Massachusetts": StateSalesTaxRate = 0.0625
    if State == "Michigan": StateSalesTexRate = 0.06
    if State == "Minnesota": StateSalesTaxRate = 0.06875
    if State == "Mississippi": StateSalesTaxRate = 0.07
    if State == "Missouri": StateSalesTaxRate = 0.04225
    if State == "Montana": StateSalesTaxRate = 0
    if State == "Nebraska": StateSalesTaxRate = 0.055
    if State == "Nevada": StateSalesTaxRate = 0.0685
    if State == "New Hampshire": StateSalesTaxRate = 0
    if State == "New Jersey": StateSalesTaxRate = 0.07
    if State == "New Mexico": StateSalesTaxRate = 0.05125
    if State == "New York": StateSalesTaxRate = 0.04
    if State == "North Carolina": StateSalesTaxRate = 0.0475
    if State == "North Dakota": StateSalesTaxRate = 0.05
    if State == "Ohio": StateSalesTaxRate = 0.0575
    if State == "Oklahoma": StateSalesTaxRate = 0.045
    if State == "Oregon": StateSalesTaxRate = 0
    if State == "Pennsylvania": StateSalesTaxRate = 0.06
    if State == "Puerto Rico": StateSalesTaxRate = 0.105
    if State == "Rhode Island": StateSalesTaxRate = 0.07
    if State == "South Carolina": StateSalesTaxRate = 0.06
    if State == "South Dakota": StateSalesTaxRate = 0.04
    if State == "Tennessee": StateSalesTaxRate = 0.07
    if State == "Texas": StateSalesTaxRate = 0.0625
    if State == "Utah": StateSalesTaxRate = 0.0595
    if State == "Vermont": StateSalesTaxRate = 0.06
    if State == "Virginia": StateSalesTaxRate = 0.053
    if State == "Washington": StateSalesTaxRate = 0.065
    if State == "West Virginia": StateSalesTaxRate = 0.06
    if State == "Wisconsin": StateSalesTaxRate = 0.05
    if State == "Wyoming": StateSalesTaxRate = 0.04
    return(UnitPrice*(1+StateSalesTaxRate))

if __name__ == '__main__': Main()

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

Итак, вы видите что-то не так с кодом? Нет? Попробуйте запустить его. Когда вы это сделаете, вы получите:

100
106.0
100
105.0

По-прежнему не вижу проблемы? Тогда у вас есть большая проблема, чем вы знаете. Вот эквивалентный код, отображаемый в Perl:

use strict;

sub Main
{
    print GetPrice(100,"Alaska"), "\n";
    print GetPrice(100,"Florida"), "\n";
    print GetPrice(100,"Michigan"), "\n";
    print GetPrice(100,"Wisconsin"), "\n";    
}

sub GetPrice
{
    my($UnitPrice,$State) = @_;
    my $StateSalesTaxRate = 0;
    $StateSalesTaxRate = 0.04 if $State eq "Alabama";
    $StateSalesTaxRate = 0 if $State eq "Alaska";
    $StateSalesTaxRate = 0.056 if $State eq "Arizona";
    $StateSalesTaxRate = 0.065 if $State eq "Arkansas";
    $StateSalesTaxRate = 0.075 if $State eq "California";
    $StateSalesTaxRate = 0.029 if $State eq "Colorado";
    $StateSalesTaxRate = 0.0635 if $State eq "Connecticut";
    $StateSalesTaxRate = 0 if $State eq "Delaware";
    $StateSalesTaxRate = 0.06 if $State eq "Florida";
    $StateSalesTaxRate = 0.04 if $State eq "Georgia";
    $StateSalesTaxRate = 0.04 if $State eq "Guam";
    $StateSalesTaxRate = 0.04 if $State eq "Hawaii";
    $StateSalesTaxRate = 0.06 if $State eq "Idaho";
    $StateSalesTaxRate = 0.0625 if $State eq "Illinois";
    $StateSalesTaxRate = 0.07 if $State eq "Indiana";
    $StateSalesTaxRate = 0.06 if $State eq "Iowa";
    $StateSalesTaxRate = 0.0615 if $State eq "Kansas";
    $StateSalesTaxRate = 0.06 if $State eq "Kentucky";
    $StateSalesTaxRate = 0.04 if $State eq "Louisiana";
    $StateSalesTaxRate = 0.055 if $State eq "Maine";
    $StateSalesTaxRate = 0.06 if $State eq "Maryland";
    $StateSalesTaxRate = 0.0625 if $State eq "Massachusetts";
    $StateSalesTexRate = 0.06 if $State eq "Michigan";
    $StateSalesTaxRate = 0.06875 if $State eq "Minnesota";
    $StateSalesTaxRate = 0.07 if $State eq "Mississippi";
    $StateSalesTaxRate = 0.04225 if $State eq "Missouri";
    $StateSalesTaxRate = 0 if $State eq "Montana";
    $StateSalesTaxRate = 0.055 if $State eq "Nebraska";
    $StateSalesTaxRate = 0.0685 if $State eq "Nevada";
    $StateSalesTaxRate = 0 if $State eq "New Hampshire";
    $StateSalesTaxRate = 0.07 if $State eq "New Jersey";
    $StateSalesTaxRate = 0.05125 if $State eq "New Mexico";
    $StateSalesTaxRate = 0.04 if $State eq "New York";
    $StateSalesTaxRate = 0.0475 if $State eq "North Carolina";
    $StateSalesTaxRate = 0.05 if $State eq "North Dakota";
    $StateSalesTaxRate = 0.0575 if $State eq "Ohio";
    $StateSalesTaxRate = 0.045 if $State eq "Oklahoma";
    $StateSalesTaxRate = 0 if $State eq "Oregon";
    $StateSalesTaxRate = 0.06 if $State eq "Pennsylvania";
    $StateSalesTaxRate = 0.105 if $State eq "Puerto Rico";
    $StateSalesTaxRate = 0.07 if $State eq "Rhode Island";
    $StateSalesTaxRate = 0.06 if $State eq "South Carolina";
    $StateSalesTaxRate = 0.04 if $State eq "South Dakota";
    $StateSalesTaxRate = 0.07 if $State eq "Tennessee";
    $StateSalesTaxRate = 0.0625 if $State eq "Texas";
    $StateSalesTaxRate = 0.0595 if $State eq "Utah";
    $StateSalesTaxRate = 0.06 if $State eq "Vermont";
    $StateSalesTaxRate = 0.053 if $State eq "Virginia";
    $StateSalesTaxRate = 0.065 if $State eq "Washington";
    $StateSalesTaxRate = 0.06 if $State eq "West Virginia";
    $StateSalesTaxRate = 0.05 if $State eq "Wisconsin";
    $StateSalesTaxRate = 0.04 if $State eq "Wyoming";
    return($UnitPrice*(1+$StateSalesTaxRate));
}

Main();

Без встроенной прагмы Perl вы даже получаете идентичный вывод:

100
106.0
100
105.0

Но при строгом включении вы получите следующее сообщение об ошибке при запуске этого Perl script:

Global symbol "$StateSalesTexRate" requires explicit package name at line 37.
Execution aborted due to compilation errors. 

Проблема в обоих примерах заключается в том, что в одной из строк вычислений есть опечатка. У меня есть "StateSalesTexRate" вместо "StateSalesTaxRate" для налога на продажу линейных компьютеров для штата Мичиган. Perl находит и скручивает эту ошибку явно. Между тем, Python поворачивает голову и смотрит в другую сторону.

Это большое дело. Представьте, что это программное обеспечение используется вашим онлайн-бизнесом, чтобы рассчитать, сколько вы берете кредитную карту клиента. Сколько времени потребуется, прежде чем вы поймете, что клиенты Мичигана получают пропуск по налогу с продаж? Когда вы это сделаете, вернитесь к клиенту и скажите "Извините, нам нужно больше денег от вас" или вы сами едите потерю?

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

Есть много вещей, которые мне очень нравятся в Python. Я понимаю, почему некоторые люди предпочитают Python для Perl. Но есть несколько вещей, которые я действительно ненавижу в Python. Это один.

Ответ 3

Чтобы запустить Python с включенными предупреждениями:

python -W all file.py

В ответ на:

Есть ли что-то, что я должен делать в рутине для моих сценариев python?

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

pip install pep8 && pep8 file.py

Ответ 4

LeoNerd дает отличное объяснение, почему в Python не используется "использование строгих" или "использование предупреждений".

В ответ на:

Есть ли что-то, что я должен делать в подпрограмме для моих сценариев python?

Вам может быть интересно запустить ваш код через статический анализатор кода, например pylint, и/или проверку форматирования кода, например pep8.

Они могут помочь найти потенциальные проблемы и предупредить флага. Они также могут многое сказать о форматировании вашего кода, который может вас заинтересовать или не интересует.

Вот достойное обоснование для их использования. И связанные с этим вопросы Stackoverflow здесь и here.

Ответ 5

На самом деле нет эквивалента. Дизайн Python со временем изменился, и многие изменения были сделаны (в частности, в 3.x), чтобы убедиться, что по умолчанию на языке по умолчанию разработчик хочет. Это очень редкая функция для существования, но необязательный флаг.

Это, вероятно, сводится к "Zen of Python" " Должен быть один - и желательно только один - простой способ сделать это. ' Дизайн Python сфокусирован на читабельности и имеет множество способов делать что-то или изменять способ работы на языке, что делает код более трудным для чтения.

Ближайшим, я бы сказал, является импорт из __future__ в старых версиях Python, чтобы ввести некоторые исправления/новые функции из более новых версий в более старые версии (например, деление, идущее от целого до плавающего деления по умолчанию). Это похоже на то, что он улучшает поведение по умолчанию, чтобы быть более разумным в стандартном случае.

Изменить: я, кажется, привлек ire от пользователей perl, которые рассматривают этот пост как атаку на Perl - он никогда не предназначался как таковой. Perl - прекрасный язык, мой оригинальный пост просто использовал плохую формулировку и не был ясен в этом объяснении. Я попытался уточнить.