Can the python interpreter fail on redeclared func

2019-02-18 20:03发布

问题:

While working on a large enough python file, I have accidentally redefined a function in the global scope. I would appreciate it if the python interpreter could warn me in those cases.

Imagine you start with this code (version 1):

#!/usr/bin/env python

... lots of code ...    

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

... lots more code ...

print foo(1)

Which works properly:

Correct

And then you want to change some things, and call it version 2. You rewrite the foo function, but you either don't realize the old one existed, or you forget to delete it. You end up with this:

#!/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)

Which doesn't work so well:

Oops!

I know python allows code like this:

def monkey():
  return "patching"
monkey = "is"
def monkey():
  return {"really": "fun"}

But it seems like using "def" that way is poor practice.

Is there any way I can get this sort of behavior:

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

Results in:

Traceback (most recent call last):
  File ..., line 3, in <module>
NameError: name 'foo' is already defined

回答1:

You can create a decorator, which can compare the name of the function and maybe store it in a dictionary. And if the key already exists, you can throw an exception from the decorator! Decorate all your functions with this decorator during development. You can then get rid of the decoration after all your testing is done!

Something like


#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!!!"


This should throw an error when run with "python --def-strict scriptname".

EDIT: Adding your hypothetical --def-strict! Also, there is no need to keep a separate __functionNames dictionary. The globals() dictionary is good enough. So editing it to reflect the same!



回答2:

I don't think that there's a flag for the Python interpreter that could help you there, but you could use a static code analysis tool like pyflakes, which would warn you about the redefinition (at least in some cases).