为什么swig在使用__getattribute__时未正确处理AttributeError?
我有一个类,它是通过SWIG从C++导出到Python的,一切运行得很好。现在我想定义一个getattribute函数,用来处理对在C++代码中内置的脚本语言定义的变量和函数的访问。不过,当我使用%pythoncode来定义getattribute函数时,它的表现并不如我所期待的。如果我找不到这些变量或函数,我应该抛出一个叫做AttributeError的异常。但是,SWIG的getattr函数对此处理得不好。
%pythoncode %{
def __getattribute__(self, attribute):
raise AttributeError(attribute)
%}
如果我这样做就没问题:
%pythoncode %{
def __getattribute__(self, attribute):
return object.__getattribute__(self, attribute)
%}
所以,SWIG生成的getattr在我应该抛出AttributeError(当找不到属性时)的时候,表现得不太正常。因此,为了我的需求,我会使用第二个例子,并在例程之前插入自己的代码来检查一个虚拟函数是否存在。如果不存在,我就让默认的对象的getattribute函数来处理。
有没有更好的方法来解决这个问题呢?
现在我发现这在普通的Python 2.7中也不工作:
class testmethods(object):
def __init__(self):
self.nofunc1 = None
self.nofunc2 = "nofunc2"
def func1(self):
print "func1"
def func2(self):
print "func2"
def __getattribute__(self, attribute):
print "Attribute:",attribute
raise AttributeError(attribute)
这会抛出异常,但并没有把责任转移到"getattr"函数上。那么应该怎么处理呢?
好吧,算了。如果对象中存在getattr,抛出异常确实是有效的。所以SWIG的行为是不正确的。
1 个回答
0
现在,我想我搞明白了:
def __getattribute__(self, attribute):
try:
defattrib = object.__getattribute__(self, attribute)
except AttributeError,e:
defattrib = None
if defattrib is not None:
return defattrib
# find attributes in user defined functions
...
# if an attribute cannot be found
raise AttributeError(attribute)
这看起来运行得很好。swig的getattr似乎能正确处理异常。所以问题只是出在我的代码上。