【问题标题】:Where error happened? exec(compile(script,"<string>",'exec'))哪里出错了?执行(编译(脚本,“<字符串>”,'执行'))
【发布时间】:2015-03-28 08:54:59
【问题描述】:

我有 2 个文件。其中一个脚本(从另一个文件调用函数)被编译并执行。我需要确定错误发生的位置:是在 user_script.py 中创建脚本(在脚本的哪一行)时出错,还是在 foo(parameter) 函数中出错。

我想捕获任何错误(SyntaxError、TypeError 等)并根据它是发生在脚本本身还是函数 foo(parameter) 中以不同方式处理它们

我展示了两个带有 NameError 的示例,但原则上我想对任何类型的错误做同样的事情。我应该参考哪些属性来区分它们?

示例 1

user_script.py

import sys
import traceback
from Catch_errors.my_function import function

script="a=1\nb=3\nfunction.foo(c)"
exec(compile(script,"<string>",'exec'))

my_function.py

class function:
    def foo(parameter):
        a = parameter
        print(a)  # or e.g. causing the error print(a+'sss')

输出:

Traceback (most recent call last):
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\pydevd.py", line 2199, in <module>
    globals = debugger.run(setup['file'], None, None)
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\pydevd.py", line 1638, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc) 
  File "C:/Users/Support/PycharmProjects/HelloWorldProject/Catch_errors/user_Script.py", line 7, in <module>
    exec(compile(script,"<string>",'exec'))
  File "<string>", line 3, in <module>
NameError: name 'c' is not defined

示例 2

user_script.py

import sys
import traceback
from Catch_errors.my_function import function

script="a=1\nb=3\nfunction.foo(2)"
exec(compile(script,"<string>",'exec'))

my_function.py

class function:
    def foo(parameter):
        a = parameter
        print(b)

输出:

Traceback (most recent call last):
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\pydevd.py", line 2199, in <module>
    globals = debugger.run(setup['file'], None, None)
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\pydevd.py", line 1638, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc) 
  File "C:/Users/Support/PycharmProjects/HelloWorldProject/Catch_errors/user_Script.py", line 5, in <module>
    script="a=1\nb=3\nfunction.foo("+b+")"
NameError: name 'b' is not defined

【问题讨论】:

  • 另外,如果你准确地发布你的错误会有所帮助。
  • 不,你的建议是错误的。它会导致 TypeError,而我的版本可以正常工作。但是,我不是在寻找创建正确脚本的方法,而是想捕捉用户可能犯的任何错误。我想捕获任何错误(SyntaxError、TypeError 等)并根据它是发生在脚本本身还是函数foo(parameter) 以不同方式处理它们
  • 如果你的script 没有编译,你会得到一个SyntaxError。然而,向我们展示实际的追溯将使我们为您提供更好的帮助。
  • 您必须自省回溯以确定异常发生在堆栈中的哪个位置。
  • 我认为我的建议没有错。我只是没有注意到您的代码中的第二个错误(首先是在类名之后调用没有括号的类变量,第二个是缺少\n。我还建议您包含“,但希望捕获任何可能的错误用户可以我想捕获任何错误(SyntaxError、TypeError 等)并根据它是发生在脚本本身还是您帖子中的函数 foo(parameter)" 而不是 cmets 中发生的不同来处理它们。

标签: python exception python-3.x exception-handling traceback


【解决方案1】:

您需要将 function.foo 设为静态方法。

class function:
    @staticmethod
    def foo(parameter):
        a = parameter
        print(a)  # or e.g. causing the error print(a+'sss')

【讨论】:

  • 那我应该参考哪些属性?当我将它设为静态时,我的案例到底有什么变化?
  • @Spu:两个更改需要 1。在 script="a=1\nb=3\nfunction.foo(2)" 语句中缺少 \n。 2.通过静态方法。有关更多信息,请参阅我的解决方案。
  • @vivek-sable 最后一个 "\n" 真的没必要,你测试过吗?
  • @huazhihao 我访问该方法没有问题。我的问题是关于错误处理的正确方法。我已经更新了帖子。
【解决方案2】:
  1. script="a=1\nb=3\nfunction.foo(2)" 语句中缺少 \n
  2. 通过静态方法:使用静态方法调用静态函数。 className.FunctionName()
  3. 按类方法:创建类方法,例如foo1() 并按类实例调用,例如类名().函数名()

test.py

import sys
import traceback
from test1 import function

script="a=1\nb=3\nfunction.foo(2)"  # of e.g. script="a=1\nb=3\function.foo(2, 3)" 
try:exec(compile(script,"<string>",'exec'))
except:print traceback.format_exc()

script="a=1\nb=3\nfunction().foo1(33)"  # of e.g. script="a=1\nb=3\function.foo(2, 3)" 
try:exec(compile(script,"<string>",'exec'))
except:print traceback.format_exc()

script="a=1\nb=3\nfunction().foo1(c)" 
try:exec(compile(script,"<string>",'exec'))
except NameError, e:
    print "NameError exception, ", traceback.format_exc()
except:
    print traceback.format_exc()

test1.py

class function:
    @staticmethod
    def foo( parameter):
        a = parameter
        print "in foo:", a  # or e.g. causing the error print(a+'sss')

    def foo1(self, parameter):
        a = parameter
        print "in foo1:", a   # or e.g. causing the error print(a+'sss')

输出:

$ python test.py 
in foo: 2
in foo1: 3
NameError exception,  Traceback (most recent call last):
  File "test.py", line 1527, in <module>
    try:exec(compile(script,"<string>",'exec'))
  File "<string>", line 3, in <module>
NameError: name 'c' is not defined

【讨论】:

  • 谢谢,这很有用,但无论如何对我的主要问题没有帮助。你知道如何区分脚本中的错误和函数中的错误吗?
  • 您正在尝试访问类中定义的foo 方法。在我的@Spu: 解决方案中,您可以看到foofoo1 方法之间的区别。如果您想调用foo 方法,那么您必须将其设为静态方法并从类名调用。如果你想调用foo1 那么你需要创建类的实例然后调用。
  • 我在访问该方法时没有问题。我的问题是关于错误处理的正确方法。我已经更新了帖子。
  • 查看我对这两个示例的评论。
  • @Spu: 现在c 没有定义。你在尝试什么?
【解决方案3】:
import sys, traceback
from Catch_errors.my_function import function

script = "a=1\nb=3\nfunction().foo(a)"

try:
    compiled_script = compile(script,"<string>",'exec')
    exec(compiled_script)
except:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    tr = traceback.extract_tb(sys.exc_info()[-1])
    print(tr)
    if "my_function.py" in tr[-1][0]:
        print("EXCEPTION IN FUNCTION "+str(tr[-1][-2])+"(), line '"+tr[-1][-1]+"'.")
        print(exc_obj.args[0])
    else:
        print('EXCEPTION IN USER SCRIPT: {}'.format(exc_obj))

【讨论】:

    猜你喜欢
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多