2015-01-29 2 views
-3

У меня есть 2 файла. В одном из них скрипт (вызов функции из другого файла) компилируется и выполняется. Мне нужно определить, где произошла ошибка: была ли ошибка при создании сценария (в какой строке скрипта) в user_script.py, или это была ошибка в функции foo (parameter).Где произошла ошибка? exec (compile (script, "<string>", 'exec'))

Я хочу, чтобы поймать любые ошибки (SyntaxError, TypeError, и т.д.) и обращаться с ними по-разному в зависимости от того, произошло ли это в себе или в функции Foo (параметр) сценария

я показываю два примера с 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 
+0

Кроме того, было бы полезно, если вы отправляете именно свою ошибку. –

+0

Нет, что вы предлагаете неправильно.Это вызывает TypeError, тогда как моя версия работает правильно. Однако я не ищу способ создания правильных скриптов, а хочу поймать любые возможные ошибки, которые мог бы сделать пользователь. Я хочу поймать любые ошибки (SyntaxError, TypeError и т. Д.) И обрабатывать их по-разному в зависимости от того, произошло ли это в самом скрипте или в функции 'foo (parameter)' – Spu

+0

Если ваш 'script' не компилировался, вы бы получите «SyntaxError». Показывая, что фактическая трассировка позволит нам помочь вам гораздо лучше. –

ответ

0
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)) 
2

Вам необходимо сделать function.foo статическим методом.

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

Каковы атрибуты, на которые я должен ссылаться тогда? Что именно меняется для моего случая, когда я делаю его статическим? – Spu

+0

@Spu: требуется два изменения 1. \ n отсутствует в сценарии = "a = 1 \ nb = 3 \ nfunction.foo (2) "2. статическим методом см. мое решение для получения дополнительной информации. –

+0

@Spu + @ staticmethod. –

0
  1. \n отсутствует в script="a=1\nb=3\nfunction.foo(2)" заявлении.
  2. По статическому методу: используйте статический метод для вызова статической функции. className.FunctionName().
  3. По методу класса: Создать метод класса, например. foo1() и вызов экземпляром класса, например. . ИмяКласса() FunctionName()

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 
+0

Спасибо, это полезно, но в любом случае не помогает моя главная проблема. Вы знаете, как различать ошибки в скрипте и ошибки в функции? – Spu

+0

Вы пытаетесь получить доступ к методу 'foo', который определяется в классе. В моем решении @Spu: вы можете увидеть разницу между методом 'foo' и' foo1'. если вы хотите вызвать метод 'foo', тогда вы должны сделать его статическим методом и вызвать из имени класса. И если вы хотите вызвать 'foo1', вам нужно создать экземпляр класса, а затем позвонить. –

+0

У меня нет проблем с доступом к методу. Мой вопрос касается правильного способа обработки ошибок. Я обновил сообщение. – Spu