python解释器在重新声明的函数上会失败吗?

python解释器在重新声明的函数上会失败吗?,python,compiler-errors,global-variables,Python,Compiler Errors,Global Variables,在处理一个足够大的python文件时,我意外地在全局范围内重新定义了一个函数。如果python解释器能够在这些情况下警告我,我将不胜感激 假设您从以下代码(版本1)开始: 哪一个工作正常: Correct 然后你想改变一些东西,称之为版本2。您重写了foo函数,但要么没有意识到旧函数的存在,要么忘记删除它。你会得到这样的结果: #!/usr/bin/env python def foo(version): if version == 2: return "Correct" r

在处理一个足够大的python文件时,我意外地在全局范围内重新定义了一个函数。如果python解释器能够在这些情况下警告我,我将不胜感激

假设您从以下代码(版本1)开始:

哪一个工作正常:

Correct
然后你想改变一些东西,称之为版本2。您重写了foo函数,但要么没有意识到旧函数的存在,要么忘记删除它。你会得到这样的结果:

#!/usr/bin/env python

def foo(version):
  if version == 2:
    return "Correct"
  return "Oops!"

... lots of code ...    

def foo(version):
  if version == 1:
    return "Correct"
  return "Oops!"

... lots more code ...

print foo(2)
这不太好用:

Oops!
我知道python允许这样的代码:

def monkey():
  return "patching"
monkey = "is"
def monkey():
  return {"really": "fun"}
但这样使用“def”似乎是一种糟糕的做法

我有没有办法得到这种行为:

#!/usr/bin/env python --def-strict
def foo():
  pass
def foo():
  pass
结果:

Traceback (most recent call last):
  File ..., line 3, in <module>
NameError: name 'foo' is already defined
回溯(最近一次呼叫最后一次):
文件…,第3行,在
NameError:已定义名称“foo”

您可以创建一个decorator,它可以比较函数的名称,并可能将其存储在字典中。如果密钥已经存在,您可以从decorator抛出异常!在开发过程中使用此装饰器装饰您的所有功能。在所有测试完成后,您就可以摆脱装饰了

差不多


#import sys

if sys.argv[1] == "--def-strict":
    def duplicateFinder(f):
        if globals().has_key(f.__name__):
            raise AttributeError, "This module already has a function %s defined" % f.__name__
        return f
else:
    def duplicateFinder(f):
        return f

@duplicateFinder
def myFunction():
    print "Hello World!"

@duplicateFinder
def myFunction():
    print "Hello World Again!!!"

当使用“python--def strict scriptname”运行时,应该会抛出一个错误


编辑:添加假设的--def strict!此外,没有必要保留单独的函数名词典。globals()字典已经足够好了。因此,编辑它以反映相同的内容

我认为Python解释器没有一个标志可以帮助您实现这一点,但是您可以使用pyflakes这样的静态代码分析工具,它会提醒您重新定义(至少在某些情况下)。

确保在实际发生的情况和所需的假设方法之间保持清晰的界限。这使它看起来像是有一个“-def strict”和相关的错误异常,但实际上没有。我认为解决这个问题的干净方法是将问题拆分为小到中等大小的模块。将模块保持在较小的范围内将使问题不太可能发生,并且更容易检测到。现在,当使用传递给Python的任何其他参数(如Python-i--def strict scriptname)运行时,这不会失败。不过,我想在sys.argv中使用“-def strict”也行。它会,条件是-,def strict应该始终是第一个参数!但总的来说,我想像
DEBUG=True
这样的变量会更好。只需更改脚本顶部的值!实际上,我在与PLY集成时遇到了这个问题,它以某种方式生成了一个关于重新定义的警告(我在6000多行输出文件中丢失了这个警告)。因此,没有装饰师也是可能的。很遗憾,您不能在语言级别执行此操作。我认为这不太正确-globals()函数在定义代码的模块()中返回作用域中的globals(),因此,如果您的装饰器与您的装饰函数位于不同的模块中,这将不起作用。代码应该是:
if func.\uuuuu name\uuuuuuuuuuu在func.\uuuuuu globals\uuuuuuuu:

#import sys

if sys.argv[1] == "--def-strict":
    def duplicateFinder(f):
        if globals().has_key(f.__name__):
            raise AttributeError, "This module already has a function %s defined" % f.__name__
        return f
else:
    def duplicateFinder(f):
        return f

@duplicateFinder
def myFunction():
    print "Hello World!"

@duplicateFinder
def myFunction():
    print "Hello World Again!!!"