Python library for control of microscope devices, supporting hardware triggers and distribution of devices over the network for performance and flexibility.
With the addition of a controller device, we will have methods that return other device instances whose interfaces then need to be checked. Something like this:
c = PriorProScanIII()
d = c.get_devices()
motors = [x for x in d if isinstance(x, MotorDevice)]
filterwheels = [x for x in d if isinstance(x, FilterwheelDevice)]
However, if instead we have:
c = Pyro4.Proxy(...) # or microscope.clients.Client
d = c.get_devices() # let's assume use of autoproxying on the server
Then all elements of d are Pyro proxies and we can't use isintance to find which ones implement which interface. We will need to do this all on the server side, with something like this:
motors = c.get_devices_of_type(MotorDevice)
But to have the code on the client side work, ignoring the proxy issue, we could have have our Interfaces as our own metaclass to overload how isinstance works. This is explained on PEP3119. The details that is not clear there, is that __instancecheck__ needs to be implemented on the metaclass (not on the abstract class that defines the interface). We would need something like this:
import abc
class SomeMeta(abc.ABCMeta):
def __instancecheck__(cls, inst):
for m in cls.__abstractmethods__:
if not hasattr(inst, m):
return False
else:
return True
class SomeABC(metaclass=SomeMeta):
@abc.abstractmethod
def nice(self):
raise NotImplementedError()
class Foo:
pass
class Bar:
def nice(self):
pass
a = Foo()
b = Bar()
print('a isinstance ', isinstance(a, SomeABC))
print('b isinstance ', isinstance(b, SomeABC))
With the addition of a controller device, we will have methods that return other device instances whose interfaces then need to be checked. Something like this:
However, if instead we have:
Then all elements of
d
are Pyro proxies and we can't useisintance
to find which ones implement which interface. We will need to do this all on the server side, with something like this:But to have the code on the client side work, ignoring the proxy issue, we could have have our Interfaces as our own metaclass to overload how
isinstance
works. This is explained on PEP3119. The details that is not clear there, is that__instancecheck__
needs to be implemented on the metaclass (not on the abstract class that defines the interface). We would need something like this: