Python方法解析之谜

Nei*_*l G 5 python pyqt boost-python python-sip

我无法弄清楚为什么这个程序失败了.

#!/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'
Run Code Online (Sandbox Code Playgroud)

我使用Boost.Python来创建libui,它暴露了类QPoint.我包括PyQt4,它有一个sip暴露的QPoint.我正在尝试完成两种类型之间的映射.

我检查过这p是一个新式的课程,为什么不__getattr__被要求p.x()

Boa*_*niv 5

这有点类似于昨天其他人遇到的问题.总之,这似乎是特殊的方法(如__getattr__,__str__,__repr__,__call__等)是不可重写的新型类的实例,即你只能在它的类型定义它们.

以下是我对该问题的解决方案的改编,希望对您有所帮助:

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!
Run Code Online (Sandbox Code Playgroud)