I am subclassing a type defined in a C module to alias some attributes and methods so that my script works in different contexts.
How is it that to get this to work, I have to tweak the dictionary of my class manually ? If I don't add a reference to DistanceTo
in the dictionnary, I get 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)
I was thinking that once __new__
had returned an instance I could still populate it with methods and attributes. Can anyone shed some light on this ?
EDIT : The module I import from is FreeCAD. The C base type is defined there. Then Vector is derived form this definition here
EDIT2 : I also tried the following :
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)
and after creating a second point, both Point3d p
returns the value of the last point for p.X
, p.Y
and p.Z
no matter what x,y,z
parameters were passed at the creation of the instance. p.x, p.y, p.z
return the expected values. It seems to indicate that the dictionary is shared between instances.
EDIT 3 : Problem solved ! The Py_TPFLAGS_BASETYPE bit is set to zero to prevent subclassing as explained in the answer below.
I don't understand why you want to add the properties dynamically. Just use:
class Point3d(App.Base.Vector):
def __init__(self, x, y, z):
super().__init__(x, y, z) # or maybe super().__init__([x, y, z])
@property
def X(self):
return self[0] # guessing that App.Base.Vector works like a list
@property.setter
def X(self, value):
self[0] = value
# Y and Z likewise.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With