python是否具有"使用严格"; 和"使用警告;" 喜欢在perl?

jon*_*hep 52 python perl warnings strict

我正在学习perl和python ...同时,不是我的设计,但必须要完成.

题:

在perl脚本中,我在我的txt的头部使用(见下文).

#!/usr/bin/env perl

use strict;
use warnings;
Run Code Online (Sandbox Code Playgroud)

对于我的python脚本,我应该做些什么吗?

Leo*_*erd 53

为了提供一个答案,或许可以避免这里的一点评论噪音,我会尝试另一个.

原始问题中的两个实际问题实际上扩展为:

use strict "vars";
use strict "refs";
use strict "subs";
use warnings;
Run Code Online (Sandbox Code Playgroud)

依次回答每个问题:

  • 这样做的结果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
Run Code Online (Sandbox Code Playgroud)
  • 其效果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
Run Code Online (Sandbox Code Playgroud)
  • 其效果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
Run Code Online (Sandbox Code Playgroud)
  • 效果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
Run Code Online (Sandbox Code Playgroud)

最后; 一些评论已经表明Python具有类似的功能__future__.但是,这不应该被认为与Perl的pragmata相似,因为后者的大多数都是词法范围的,并且可以根据需要在小范围内启用或禁用; 其中的Python __future__只对整个源文件启用.

例如.

use strict;
use warnings;

my $total;

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

{
   no warnings 'uninitialized';
   printf "The total is %d\n", $total;
}
Run Code Online (Sandbox Code Playgroud)

一个有点人为的例子,但是这个例子演示了no warnings 'uninitialized'如何在printf语句中禁用关于使用未初始化值的警告,同时仍然在其他地方保持启用其他警告.


总而言之:Python没有use strict或任何近似等价,因为它提供的任何安全功能都是强制性的,或者在Python语言中不可用,并且没有use warnings.它提供的那些功能仅在文件级启用,并且不能针对每个范围有选择地启用或禁用.


编辑:实际上我已经被告知Python确实有一些可控制的警告标志,可以根据需要启用和禁用.

  • 非常翔实,有点过头但这是我更喜欢学习的方式.您是否介意链接或扩展"编辑"部分?只是对启用和禁用语法感到好奇. (4认同)

小智 30

正如其他用户发布的那样,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()
Run Code Online (Sandbox Code Playgroud)

此代码计算包括销售税在内的购买成本.虽然有更有效的方法来做到这一点,但它只是一个例子.

那么,你看到代码有什么问题吗?没有?尝试运行它.当你得到:

100
106.0
100
105.0
Run Code Online (Sandbox Code Playgroud)

还是没有看到问题?然后你遇到了比你知道的更大的问题.这是在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();
Run Code Online (Sandbox Code Playgroud)

如果没有启用Perl的严格编译指示,您甚至可以获得相同的输出:

100
106.0
100
105.0
Run Code Online (Sandbox Code Playgroud)

但是在严格打开的情况下,运行此Perl脚本时会出现以下错误消息:

Global symbol "$StateSalesTexRate" requires explicit package name at line 37.
Execution aborted due to compilation errors. 
Run Code Online (Sandbox Code Playgroud)

两个示例中的问题在于其中一个计算行中存在拼写错误.对于密歇根州的线路计算销售税,我有"StateSalesTexRate"而不是"StateSalesTaxRate".Perl明确地发现并压制了这个bug.与此同时,Python转向了另一个方向.

这是一个大问题.想象一下,您的在线业务正在使用此软件来计算您对客户信用卡收取的费用.在您意识到密歇根州的客户获得销售税通行证之前需要多长时间?当你这样做的时候,你会回到客户面前说"对不起,我们需要你更多的钱"或者你自己吃亏了吗?

当然,任何使用这种编码算法来计算销售税的公司都可能存在更大的问题.但是你可以通过这个例子清楚地看到Perl中的严格编译指示是什么以及为什么我和其他人认为它应该是任何脚本语言的基本特征.

我真的很喜欢Python.我明白为什么有些人喜欢Python而不喜欢Perl.但是有一些我真正讨厌Python的事情.这是一.

  • 我希望我可以投票一百次!在这种情况下,`strict`已经救了我很多次。您的示例很简单,但请想象一下在代码中发现这种类型的错误,该错误用于分析医学数据并指导治疗决策!您可能认为它牵强附会,但我已经看到了!“严格使用”可以挽救生命! (3认同)
  • 公平地说,这是极其丑陋的代码,任何编码器都​​会因为这样的错误而重新格式化。如果不是整个代码块,IDE 也会标记这个变量。举一个不切实际的例子并不能真正说明你的观点。事实上,您必须像这样向后倾斜才能找到需要此严格模式的示例,这表明很少需要严格模式。 (2认同)
  • @Nearoo 你假设你有一个不错的工具集。3 个月前,我正在编写一个 700 行的脚本,用不太像 Visual Basic 的东西编写,嵌入到现代的当前产品中。所提供的编辑器完全没有智慧。我在格式化该脚本时投入了我能想到的所有最佳实践,但“选项显式”仍然多次挽救了我的屁股。 (2认同)

Jia*_*ian 9

要在启用警告的情况下运行Python:

python -W all file.py
Run Code Online (Sandbox Code Playgroud)

回应:

对于我的python脚本,我应该做些什么吗?

我认为确保您的代码符合PEP 8通常是个好主意.在另一个答案中提到,您可以以编程方式执行此操作:

pip install pep8 && pep8 file.py
Run Code Online (Sandbox Code Playgroud)

  • 当我运行 pep8 时,它说:“pep8 已重命名为 pycodestyle(GitHub 问题 #466),未来版本中将删除 pep8 工具的使用。请安装并使用 `pycodestyle`。” (2认同)

Sea*_*ean 5

LeoNerd提供了一个很好的解释,说明为什么在Python中没有"使用严格"或"使用警告".

回答:

对于我的python脚本,我应该做些什么吗?

您可能有兴趣通过静态代码分析器(如pylint)和/或代码格式检查(如pep8)来运行代码.

他们可以帮助发现潜在的问题,并标记警告.他们还有很多关于代码格式的说法,您可能对此感兴趣,也可能不感兴趣.

这是他们使用的合理理由.相关的Stackoverflow问题在这里这里.