Supposing the following code:
import cv2 #3rd party python module (C extension!!)
a0 = cv2.KeyPoint(x=100,y=200,_size=20, _angle=1, _response=2, _octave=3, _class_id=4)
print "undesired output, desired syntax"
print a0
print str(a0)
print repr(a0)
print "desired output, undesired syntax"
print a0.pt, a0.size, a0.angle, a0.response, a0.octave, a0.class_id
which prints out:
undesired output, desired syntax
<KeyPoint 0x7fc2575a9a20>
<KeyPoint 0x7fc2575a9a20>
<KeyPoint 0x7fc2575a9a20>
desired output, undesired syntax
(100.0, 200.0) 20.0 1.0 2.0 3 4
How do I get the desired output with the desired syntax?
As far as I can see there are the following approaches:
derive my own class from KeyPoint and implement str and repr there: unwanted as a) some functions in cv2 expect a list of cv.KeyPoint objects and conversion would slow down the code b) the additional class layer makes the code more complex
monkey patch KeyPoint: would be nice but does not work (see code below). In addition I don't know if the functions in cv2 expecting lists of KeyPoint would accept such a modified class.
monkey patch a0: would be less nice but does not work neither (see code below).
register a global formatting function for objects of type cv2.KeyPoint that gets called whenever such an object has to be converted to string. (Approach similar to copyreg for pickle serialization). I didn't find any hint that such a registry actually exists.
My monkey patch intents:
def custom_str(self):
return " ".join(self.pt, self.size, self.angle, self.response, self.octave, self.class_id)
try:
print "patching class"
cv2.KeyPoint.__str__ = custom_str
print str(a0)
a1 = cv2.KeyPoint(x=100,y=200,_size=20, _angle=1, _response=2, _octave=3, _class_id=4)
print str(a1)
except Exception, e:
print "failed"
print e
try:
print "patching object"
a0.__str__ = custom_str
print str(a0)
except Exception, e:
print "failed"
print e
output:
patching class
failed
'builtin_function_or_method' object attribute '__str__' is read-only
patching object
failed
'cv2.KeyPoint' object attribute '__str__' is read-only