Python 2.7 在引发RRontimeError时从R捕获回溯

Python 2.7 在引发RRontimeError时从R捕获回溯,python-2.7,python-2.x,rpy2,traceback,Python 2.7,Python 2.x,Rpy2,Traceback,Python类通过rpy2执行R函数,我希望能够在R函数生成错误时捕获R的回溯 R代码是遗留的,因此修改它将是非常危险的;我更愿意在Python方面做一些事情 下面是Python代码当前的样子: from rpy2.rinterface import RRuntimeError from rpy2.robjects import DataFrame from rpy2.robjects.packages import InstalledPackage class RAdapter(BaseRA

Python类通过rpy2执行R函数,我希望能够在R函数生成错误时捕获R的回溯

R代码是遗留的,因此修改它将是非常危险的;我更愿意在Python方面做一些事情

下面是Python代码当前的样子:

from rpy2.rinterface import RRuntimeError
from rpy2.robjects import DataFrame
from rpy2.robjects.packages import InstalledPackage

class RAdapter(BaseRAdapter):
    _module = None # type: InstalledPackage

    def call_raw(self, function_name, *args, **kwargs):
        # type: (str, tuple, dict) -> DataFrame
        """
        Invokes an R function and returns the result as a DataFrame.
        """
        try:
            return getattr(self._module, function_name)(*args, **kwargs)
        except RRuntimeError as e:
            # :todo: Capture traceback from R and attach to `e`.
            e.context = {'r_traceback': '???'}
            raise

    ...
我应该如何修改call_raw,以便在R函数导致错误时从R捕获回溯?

回溯是在R中生成错误回溯的go-to函数。使用rpy2.robjects.R,您可以计算回溯函数,并将结果直接存储到Python变量中

请注意,对于RPY2v2.8.x:回溯的结果是一个成对列表,它是,但是有一个。为了使代码更易于调试,它使用unlist将成对列表转换为列表

请注意,回溯还将回溯发送到stdout,据我所知,除了[暂时]覆盖sys.stdout之外,没有其他方法可以避免这种情况

以下是RAdapter.call_raw如何捕获R回溯:

from rpy2.rinterface import RRuntimeError
from rpy2.robjects import DataFrame
from rpy2.robjects.packages import InstalledPackage

class RAdapter(BaseRAdapter):
    _module = None # type: InstalledPackage

    def call_raw(self, function_name, *args, **kwargs):
        # type: (str, tuple, dict) -> DataFrame
        """
        Invokes an R function and returns the result as a DataFrame.
        """
        try:
            return getattr(self._module, function_name)(*args, **kwargs)
        except RRuntimeError as e:
            # Attempt to capture the traceback from R.
            try:
                e.context = {
                    # :kludge: Have to use `unlist` because `traceback`
                    #   returns a pairlist, which rpy2 doesn't know how
                    #   to repr.
                    'r_traceback': '\n'.join(r('unlist(traceback())'))
                }
            except Exception as traceback_exc:
                e.context = {
                    'r_traceback':
                        '(an error occurred while getting traceback from R)',

                    'r_traceback_err':  traceback_exc,
                }

            raise

    ...
用rpy2==2.8.3进行测试。

rpy2可以很好地处理R对列表。但是,它们的表示方法_urepr_uuu似乎有一个缺陷:R向量的常规_urepr_uuu使用切片,切片不可用于成对列表对象

>>> from rpy2.robjects import baseenv
>>> opts = baseenv['.Options']
>>> opts.typeof # this is a pairlist
2
>>> print(opts) # working
...
>>> str(opts) # working
>>> opts.items() # working
>>> repr(opts) # ValueError: Cannot handle R type 2

谢谢你的澄清!我已登录以便跟进。