- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有以下两个 C++ 异常的简单层次结构:
class LIB_EXP ClusterException : public std::exception {
public:
ClusterException() { }
ClusterException(const std::string& what) { init(what); }
virtual const char* what() const throw() { return what_.c_str(); }
virtual ~ClusterException() throw() {}
virtual ClusterException* clone() { return new ClusterException(*this); }
protected:
void init(const std::string& what) { what_ = what; }
private:
std::string what_;
};
class LIB_EXP ClusterExecutionException : public ClusterException {
public:
ClusterExecutionException(const std::string& jsonResponse);
std::string getErrorType() const throw() { return errorType_; }
std::string getClusterResponse() const throw() { return clusterResponse_; }
virtual ~ClusterExecutionException() throw() {}
virtual ClusterExecutionException* clone() { return new ClusterExecutionException(*this); }
private:
std::string errorType_;
std::string clusterResponse_;
};
然后我使用 Boost-Python 将它们导出到 Python,如下所示。请注意我使用 bases
以确保在翻译中保留继承关系:
class_<ClusterException> clusterException("ClusterException", no_init);
clusterException.add_property("message", &ClusterException::what);
clusterExceptionType = clusterException.ptr();
register_exception_translator<ClusterException>(&translateClusterException);
class_<ClusterExecutionException, bases<ClusterException> > clusterExecutionException("ClusterExecutionException", no_init);
clusterExecutionException.add_property("message", &ClusterExecutionException::what)
.add_property("errorType", &ClusterExecutionException::getErrorType)
.add_property("clusterResponse", &ClusterExecutionException::getClusterResponse);
clusterExecutionExceptionType = clusterExecutionException.ptr();
register_exception_translator<ClusterExecutionException>(&translateClusterExecutionException);
然后是异常翻译方法:
static PyObject *clusterExceptionType = NULL;
static void translateClusterException(ClusterException const &exception) {
assert(clusterExceptionType != NULL);
boost::python::object pythonExceptionInstance(exception);
PyErr_SetObject(clusterExceptionType, pythonExceptionInstance.ptr());
}
static PyObject *clusterExecutionExceptionType = NULL;
static void translateClusterExecutionException(ClusterExecutionException const &exception) {
assert(clusterExecutionExceptionType != NULL);
boost::python::object pythonExceptionInstance(exception);
PyErr_SetObject(clusterExecutionExceptionType, pythonExceptionInstance.ptr());
}
我创建了以下抛出异常的测试 C++ 函数:
static void boomTest(int exCase) {
switch (exCase) {
case 0: throw ClusterException("Connection to server failed");
break;
case 1: throw ClusterExecutionException("Error X while executing in the cluster");
break;
default: throw std::runtime_error("Unknown exception type");
}
}
最后是调用我的 C++ boomTest
的 Python 测试代码:
import cluster
reload(cluster)
from cluster import ClusterException, ClusterExecutionException
def test_exception(exCase):
try:
cluster.boomTest(exCase)
except ClusterException as ex:
print 'Success! ClusterException gracefully handled:' \
'\n message="%s"' % ex.message
except ClusterExecutionException as ex:
print 'Success! ClusterExecutionException gracefully handled:' \
'\n message="%s"' \
'\n errorType="%s"' \
'\n clusterResponse="%s"' % (ex.message, ex.errorType, ex.clusterResponse)
except:
print 'Caught unknown exception: %s "%s"' % (sys.exc_info()[0], sys.exc_info()[1])
def main():
print '\n************************ throwing ClusterException ***********************************************************************'
test_exception(0)
print '\n************************ throwing ClusterExecutionException **************************************************************'
test_exception(1)
print '\n************************ throwing std::runtime_error *********************************************************************'
test_exception(2)
if __name__ == "__main__":
main()
到这里为止一切正常。但是,如果我从 Python 中删除 ClusterExecutionException
捕获处理程序,则该异常将被捕获并回退到未知异常,而不是作为其基础 ClusterException
被捕获。
我在 Boost-Python 中尝试注册 ClusterExecutionException
的异常翻译以将其注册为其基础 ClusterException
然后它被“多态”捕获但后来它赢了'不会被捕获为 ClusterExecutionException
。如何使 ClusterExecutionException
被捕获为 ClusterException
和 ClusterExecutionException
?我当然尝试将此 ClusterExecutionException
异常注册为 ClusterException
和 ClusterExecutionException
但它遵循最后的获胜策略,并且只有一个不能同时使用。
还有其他方法可以解决这个问题吗?
更新 1: 这个问题的全部目标是在 C++ 端找出 except
Python 语句的类型,例如except ClusterException as ex:
在 C++ 端内部是未知的。 Boost.Python的异常翻译会调用异常动态类型对应的translate函数,Python catch静态类型未知。
更新 2: 建议将 Python 代码更改为以下内容,即添加 print(type(ex).__bases__)
给出:
def test_exception(exCase):
try:
cluster.boomTest(exCase)
except ClusterException as ex:
print(type(ex).__bases__)
print 'Success! ClusterException gracefully handled:' \
'\n message="%s"' % ex.message
except ClusterExecutionException as ex:
print(type(ex).__bases__)
print 'Success! ClusterExecutionException gracefully handled:' \
'\n message="%s"' \
'\n errorType="%s"' \
'\n clusterResponse="%s"' % (ex.message, ex.errorType, ex.clusterResponse)
except:
print 'Caught unknown exception: %s "%s"' % (sys.exc_info()[0], sys.exc_info()[1])
和输出:
************************ throwing ClusterException ***********************************************************************
(<type 'Boost.Python.instance'>,)
Success! ClusterException gracefully handled:
message="Connection to server failed"
************************ throwing ClusterExecutionException **************************************************************
(<class 'cluster.ClusterException'>,)
Success! ClusterExecutionException gracefully handled:
message="Error X while executing in the cluster"
errorType="LifeCycleException"
clusterResponse="{ "resultStatus": "Error", "errorType": "LifeCycleException", "errorMessage": "Error X while executing in the cluster" }"
表示继承关系是从 Python 中“看到”的。但是多态处理还是不行。
UPDATE 3 这是运行 VS dumpbin.exe
的输出:
我使用的命令是:
dumpbin.exe /EXPORTS /SYMBOLS C:\ClusterDK\x64\Debug\ClusterDK.dll > c:\temp\dumpbin.out
以及输出的相关部分:
Microsoft (R) COFF/PE Dumper Version 11.00.50727.1
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file C:\ClusterDK\x64\Debug\ClusterDK.dll
File Type: DLL
Section contains the following exports for ClusterDK.dll
00000000 characteristics
5A1689DA time date stamp Thu Nov 23 09:42:02 2017
0.00 version
1 ordinal base
78 number of functions
78 number of names
ordinal hint RVA name
8 7 00004485 ??0ClusterException@cluster@@QEAA@AEBV01@@Z = @ILT+13440(??0ClusterException@cluster@@QEAA@AEBV01@@Z)
9 8 00001659 ??0ClusterException@cluster@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z = @ILT+1620(??0ClusterException@cluster@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
10 9 00001F1E ??0ClusterException@cluster@@QEAA@XZ = @ILT+3865(??0ClusterException@cluster@@QEAA@XZ)
11 A 00004D4F ??0ClusterExecutionException@cluster@@QEAA@AEBV01@@Z = @ILT+15690(??0ClusterExecutionException@cluster@@QEAA@AEBV01@@Z)
12 B 000010AA ??0ClusterExecutionException@cluster@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z = @ILT+165(??0ClusterExecutionException@cluster@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
27 1A 000035D0 ??1ClusterException@cluster@@UEAA@XZ = @ILT+9675(??1ClusterException@cluster@@UEAA@XZ)
28 1B 00003C7E ??1ClusterExecutionException@cluster@@UEAA@XZ = @ILT+11385(??1ClusterExecutionException@cluster@@UEAA@XZ)
37 24 00002BD5 ??4ClusterException@cluster@@QEAAAEAV01@AEBV01@@Z = @ILT+7120(??4ClusterException@cluster@@QEAAAEAV01@AEBV01@@Z)
38 25 000034D1 ??4ClusterExecutionException@cluster@@QEAAAEAV01@AEBV01@@Z = @ILT+9420(??4ClusterExecutionException@cluster@@QEAAAEAV01@AEBV01@@Z)
46 2D 000D2220 ??_7ClusterException@cluster@@6B@ = ??_7ClusterException@cluster@@6B@ (const cluster::ClusterException::`vftable')
47 2E 000D2248 ??_7ClusterExecutionException@cluster@@6B@ = ??_7ClusterExecutionException@cluster@@6B@ (const cluster::ClusterExecutionException::`vftable')
52 33 00004BB5 ?clone@ClusterException@cluster@@UEAAPEAV12@XZ = @ILT+15280(?clone@ClusterException@cluster@@UEAAPEAV12@XZ)
53 34 00004D31 ?clone@ClusterExecutionException@cluster@@UEAAPEAV12@XZ = @ILT+15660(?clone@ClusterExecutionException@cluster@@UEAAPEAV12@XZ)
61 3C 00001D43 ?getErrorType@ClusterExecutionException@cluster@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ = @ILT+3390(?getErrorType@ClusterExecutionException@cluster@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
69 44 0000480E ?init@ClusterException@cluster@@IEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z = @ILT+14345(?init@ClusterException@cluster@@IEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
78 4D 000032FB ?what@ClusterException@cluster@@UEBAPEBDXZ = @ILT+8950(?what@ClusterException@cluster@@UEBAPEBDXZ)
Summary
4000 .data
5000 .idata
12000 .pdata
54000 .rdata
2000 .reloc
1000 .rsrc
C9000 .text
1000 .tls
最佳答案
我的python技能比较生疏,这个没测试过,所以这个可能需要进一步改进,但是尝试添加异常翻译方法来处理基类异常类型:
static PyObject *clusterExecutionAsClusterExceptionType = NULL;
static void translateClusterExecutionAsClusterException(ClusterException const &exception) {
ClusterExecutionException* upcasted = dynamic_cast<ClusterExecutionException*>(&exception);
if (upcasted)
{
assert(clusterExecutionAsClusterExceptionType != NULL);
boost::python::object pythonExceptionInstance(*upcasted);
PyErr_SetObject(clusterExecutionAsClusterExceptionType, pythonExceptionInstance.ptr());
}
}
register_exception_translator<ClusterException>(&translateClusterExecutionAsClusterException);
关于python - 多态异常处理 : How to catch subclass exception?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46420476/
我想知道在从另一个扩展的类中创建对象的这两种方法之间是否存在任何功能差异。 我只是在处理基本的继承,除了 Cat extends Mammal 之类的东西之外没有什么复杂的。 最佳答案 ParentC
class superClass {} class subClass extends superClass{} public class test { public static void m
我有一个跨很多很多项目的 C# 解决方案。我创建了一个从 Systme.Diagnostics.Tracing.EventSource 继承的跟踪类,称为 MyCustomEventSource,它处
考虑以下示例,其中 Student 继承自 Person: function Person(name) { this.name = name; } Person.prototype.say =
基本上是标题所说的内容,但有一些详细说明。我有一个带有几个子类的父类(super class)。我需要一个 ArrayList 来保存两种类型的子类,因此需要 SuperClass 类型的 Array
我正在阅读 mughal 的 SCJP(第 3 版)(我遇到的最好的 SCJP 书),在第 727 页上,它说了以下内容: class MyIntList extends ArrayList {}
我使用方法 Object process( JobContext jobContext ); 以及名为 JobProcessImpl 的 impl 来定义 JobProcess。每当执行此 JobPr
如果我想编写一个采用可变数量“TDerived”的方法,其中 TDerived 是类“Base”的任何子类,有什么办法可以做到这一点吗? 以下代码仅适用于单个特定的指定子类: void doStuff
有没有人(本地)弄清楚如何对 SKNode 进行子类化以包含通过关节连接的多个物体 - 例如汽车? 似乎没有办法将子类的关节添加到父场景的物理世界属性中。 此外,当尝试编译并运行下面的对象时,即使没有
我正在尝试编写 Node 库的扩展。该库导出一个扩展 EventEmitter 的类(class LibClass extends EventEmitter)。它负责建立一个 websocket 连接
Tensorflow 有一些 docs用于子类化 (tf) Keras Model 和 Layer。 但是,尚不清楚使用哪个“模块”或“ block ”(例如,几个层的集合)。 由于从技术上讲它是几个
我正在尝试对 android.os.AsyncTask 类进行通用子类化。我基本上只想给它添加一个属性。问题是,我仍然希望能够将它用作匿名类。 import android.content.C
是否可以在 swift 中对通用结构进行子类化? 假设我们有一个结构: struct Foo {} 我想要“子类化”它以添加一些功能: struct Something {} struct Bar
class A: pass class B(A): pass ListOfA = List[A] list_of_a : ListOfA = [A(), A()] for e in [
我想通过打印选择器和参数来拦截发送到代理对象的消息。即使代理没有实现它们并且没有目标对象。请帮忙。我已经查看了几个选项和 Apple 文档,但他们假设您已经知道目标对象。我想干净地完成此操作,而不会出
我有一个使用核心数据并有两个目标的项目。这些目标有几个共享实体。目前,我正在维护两个具有重复实体的独立模型,在我看来,这效率不高。 有没有办法将共享数据模型作为具体目标中数据模型的父级? 最佳答案 我
我收到以下错误: Could not find matching constructor for: org.crawler.CrawlerUtils$fetch(org.series.crawler.
在 Knockout 中,我有一个 Setting 实体数组,它们可能具有不同的类型(即设置实体的“子类”)。这些类型是动态的,用户可以在 UI 中更改它们。根据设置实体的类型,它需要不同的对象属性,
我有一个ArrayClass并且mergeSortArray扩展了它。并且 mergeSortArray 包含一个 mergeSort() 方法。但是,由于我使用 super 从父类(super cl
我是 PyTorch 的新手,在使用不同的工具包一段时间后尝试它。 我想了解如何对自定义层和函数进行编程。作为一个简单的测试,我写了这个: class Testme(nn.Module):
我是一名优秀的程序员,十分优秀!