Python方法解析之谜 [英] Python method resolution mystery
问题描述
我不知道为什么该程序失败.
I can't figure out why this program is failing.
#!/usr/bin/env python
from __future__ import division, print_function
from future_builtins import *
import types
import libui as ui
from PyQt4 import QtCore
import sip
p = ui.QPoint()
q = QtCore.QPoint()
def _q_getattr(self, attr):
print("get %s" % attr)
value = getattr(sip.wrapinstance(self.myself(), QtCore.QPoint), attr)
print("get2 %s returned %s" % (attr, value))
return value
p.__getattr__ = types.MethodType(_q_getattr, p)
print(p.__getattr__('x')()) # Works! Prints "0"
print(p.x()) # AttributeError: 'QPoint' object has no attribute 'x'
我使用Boost.Python创建了libui,它公开了QPoint类.我也包括PyQt4,它有一个饮酒者暴露的QPoint.我正在尝试完成两种类型之间的映射.
I used Boost.Python to create libui, which exposes the class QPoint. I aso included PyQt4, which has a sip-exposed QPoint. I'm trying to accomplish a mapping between the two types.
我检查了p
是一个新样式的类,那么为什么__getattr__
不被p.x()
调用?
I checked that p
is a new-style class, so why isn't __getattr__
being called for p.x()
?
推荐答案
This is somewhat similar to the issue someone else has encountered just yesterday. In short, it seems like special methods (like __getattr__
, __str__
, __repr__
, __call__
and so on) aren't overridable in new-style class instance, i.e. you can only define them in its type.
这是我针对该问题的解决方案的改编版本,有望对您有用:
And here's an adaptation of my solution for that problem which should hopefully work for yours:
def _q_getattr(self, attr):
print("get %s" % attr)
return getattr(self, 'x')
def override(p, methods):
oldType = type(p)
newType = type(oldType.__name__ + "_Override", (oldType,), methods)
p.__class__ = newType
override(p, { '__getattr__': _q_getattr})
print(p.__getattr__('x')()) # Works! Prints "0"
print(p.x()) # Should work!
这篇关于Python方法解析之谜的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!