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

时间:2012-11-16 23:01:51

标签: python perl warnings strict

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

问题:

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

#!/usr/bin/env perl

use strict;
use warnings;

我的python脚本在日常工作中应该做些什么吗?

6 个答案:

答案 0 :(得分:51)

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

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

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的pragmata相似,因为后者的大多数都是词法范围的,并且可以根据需要在小范围内启用或禁用;哪个Python的__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语言中不可用,并且没有{{1} }。它提供的那些功能仅在文件级别启用,并且无法为每个范围选择性地启用或禁用。


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

答案 1 :(得分:22)

正如其他用户发布的那样,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脚本时会出现以下错误消息:

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

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

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

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

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

答案 2 :(得分:7)

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

python -W all file.py

回应:

  

我的python脚本在日常工作中应该做些什么吗?

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

pip install pep8 && pep8 file.py

答案 3 :(得分:5)

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

回答:

  

我的python脚本在日常工作中应该做些什么吗?

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

他们可以帮助发现潜在的问题,并标记警告。他们对代码的格式也有很多话要说,你可能对此感兴趣,也可能不感兴趣。

以下是decent rationale for their use.及相关的Stackoverflow问题herehere

答案 4 :(得分:0)

实际上没有任何等价物。 Python的设计随着时间的推移而发展,并且已经进行了许多更改(特别是在3.x中)以确保语言中的默认值是开发人员默认需要的。功能很少存在,但是可选标志。

这可能归结为The Zen of Python's '应该有一个 - 最好只有一个 - 显而易见的方法。' Python的设计主要围绕可读性,并且有很多做事的方式或改变语言的工作方式使代码更难阅读。

我认为,最接近的是在旧版本的Python中从__future__导入,以便将较新版本中的一些修复/新功能引入旧版本(例如默认情况下从整数到浮动除法)。这与在标准情况下改进默认行为更为明智的意义相似。

编辑:我似乎从perl用户那里吸引了愤怒,他们认为这篇文章是对Perl的攻击 - 它从未打算如此。 Perl是一门优秀的语言,我原来的帖子只是使用了不好的措辞而且在解释中并不清楚。我试图澄清一下。

答案 5 :(得分:0)

这不是编译时错误,但是Python有许多linter可以识别与Perl的“ use strict”相同类型的错误:

使用以下命令考虑一个名为tmp.py的Python文件:

def foo():
    a = 1
    b = 2
    return a

flake8 tmp.py将返回:

tmp.py:13:5: F841 local variable 'b' is assigned to but never used

除了flake8外,请检出mypy进行更高级的类型检查,并检出pylint来强制执行某些编码样式。与任何编程语言一样,没有什么可以阻止您在代码库上使用多个linter –实际上,每个linter都有不同的重点,因此鼓励这样做。