Имеет ли python "use strict;" и " use warnings;", как в perl?

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

вопрос:

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

#!/usr/bin/env perl

use strict;
use warnings;

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

5 ответов


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

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

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

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

  • эффект use strict "vars" является причиной ошибки времени компиляции для ссылки на переменную без предварительного объявления о ее существовании (например, по умолчанию в более статических языках, таких как C, 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, поскольку большинство последних лексически ограничены, и может быть включен или отключен в небольших областях по мере необходимости; где __future__ включен только для всего исходного файла.

например.

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. Те функции, которые он предоставляет, включены только на уровне файла и не могут быть выборочно включены или отключены для каждой области.


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


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

несомненно, будут преданные питона, которые обижаются на это утверждение. Я слышал, что некоторые говорят, что им не нужны строгости. Я нахожу, что те, кто говорит это, как правило, не знают, что строгий покупает вас. Рассмотрим следующий блок кода в 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:

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. Это первый.


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

python -W all file.py

в ответ на:

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

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

pip install pep8 && pep8 file.py

LeoNerd дает отличное объяснение, почему в Python нет "use strict" или "use warnings".

в ответ на:

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

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

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

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


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

Это, вероятно, сводится к Дзен питона