Hi All.
I’ve been trying to subclass the Motor class in Pyepics, so I can add my own variables and methods to it, and I’ve run into problems.
Adding new methods seems to work just fine, but I find a strange problem when I try to add new ‘instance variables’ to my subclass.
They all end up having value ‘None’ if I add them after doing the __init__ of the base Motor class. Worse, if I try to define
them before I call the epics.Motor.__init__(), I get an exception from motor.py. This is not normal Python behaviour, as far as I know, and I’ve added code to test that I can subclass this way with a ‘simple’ python class, as shown below.
Any ideas what I am doing wrong, or why epics.Motor can’t be subclassed in this way?
Any suggestions as to how I can subclass it and add my own variables, or why I shouldn’t?
I suppose an alternative would be to make a class that contains an epics.Motor object rather than subclass it.
Thanks,
Terry
import epics #get the Motor class (and everything else) from Pyepics
class myBaseClass(): #make a simple base class so I can test that subclassing works as expected
def __init__(self,*args,**kwargs):
self.baseVar=kwargs.pop('mssg') #have some variable just so we aren't empty
class myClass(myBaseClass): #subclass myBaseClass
def __init__(self,*args,**kwargs):
self.before_init_base_instance_variable=1 #add an instance variable before I init base class. This works
myBaseClass.__init__(self,*args,**kwargs) #init the base class
self.new_instance_variable=1000 #here’s a new instance variable that I want in my subclass
self.another_new_instance_variable=2000 #here’s another new instance variable that I want in my subclass
class myMotor(epics.Motor): #subclass epics.Motor
def __init__(self,*args,**kwargs):
# self.before_init_instance_variable=1 #This would get an exception from motor.py, so I comment it out
epics.Motor.__init__(self,*args,**kwargs) #call the epics.Motor ‘s __init__ to set it up
self.new_instance_variable=1000 #here’s a new instance variable that I want in my subclass
self.another_new_instance_variable=2000 #here’s a new instance variable that I want in my subclass
c=myClass(mssg='fred')
print c.before_init_base_instance_variable #This works.
print c.baseVar #print the variable in the myBaseClass just to show it worked
print c.new_instance_variable #access the variable I added. It works
print c.another_new_instance_variable #access the second variable I added. It works
c.new_instance_variable=3000
print c.new_instance_variable #see if writing to it worked. It does
m=myMotor('SR10BM01DMC05:MTR01') #create an instance of my subclass, based on epics.Motor
# print m.before_init_base_instance_variable #Just trying to define this causes an exception so it’s commented out
print m.new_instance_variable #try to access the variable I added, get 'None'
print m.another_new_instance_variable #try to access the second variable I added, get 'None'
m.new_instance_variable=3000
print m.new_instance_variable #see if writing to it worked. Get 'None'
This is what I get when I run the code.
1 #this is from the instance variable I added before calling myBaseClass.__init__ and it works
Fred #this is the variable in the the myBaseClass and it is initialised as expected.
1000 #The next three are instance variables I added to my sublass based on myBaseClass
2000 #and they work as expected
3000 #This is the instance variable I wrote to and it worked.
#The next three are from the instance variables I added to the subclass based on epics.Motor
None #should have been 1000
None #should have been 2000
None #should have been 3000