【发布时间】:2016-04-19 19:34:35
【问题描述】:
我将 C 模块中定义的类型子类化为一些属性和方法的别名,以便我的脚本在不同的上下文中工作。
如何让它工作,我必须手动调整我班级的字典?如果我不在字典中添加对DistanceTo 的引用,我会得到Point3d has no attribute named DistanceTo。
class Point3d(App.Base.Vector):
def __new__(cls, x, y, z):
obj = super(Point3d, cls).__new__(cls)
obj.x, obj.y, obj.z = x, y, z
obj.__dict__.update({
'X':property(lambda self: self.x),
'Y':property(lambda self: self.y),
'Z':property(lambda self: self.z),
'DistanceTo':lambda self, p: self.distanceToPoint(p)})
return obj
def DistanceTo(self, p): return self.distanceToPoint(p)
我在想,一旦__new__ 返回了一个实例,我仍然可以用方法和属性填充它。任何人都可以对此有所了解吗?
编辑:我导入的模块是 FreeCAD。 C 基类型定义为there。然后 Vector 是从这个定义中导出的 here
EDIT2:我还尝试了以下方法:
class Point3d(App.Base.Vector):
def __new__(cls, x, y, z):
obj = super(Point3d, cls).__new__(cls)
obj.x, obj.y, obj.z = x, y, z
obj.__dict__.update({
'X': x, 'Y': y, 'Z': z,
'DistanceTo':lambda self, p: self.distanceToPoint(p)})
return obj
def DistanceTo(self, p): return self.distanceToPoint(p)
并且在创建第二个点之后,Point3d p 都会返回 p.X、p.Y 和 p.Z 的最后一个点的值,无论在创建实例时传递了什么 x,y,z 参数。 p.x, p.y, p.z 返回预期值。这似乎表明字典在实例之间共享。
编辑 3:问题解决了! Py_TPFLAGS_BASETYPE 位设置为零以防止子类化,如下面的答案所述。
【问题讨论】:
标签: python subclassing python-c-api freecad