Skip to content

Instantly share code, notes, and snippets.

@psy0rz
Last active June 27, 2019 07:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save psy0rz/ac804b48d3a3133ab84fc622c8c19f1f to your computer and use it in GitHub Desktop.
Save psy0rz/ac804b48d3a3133ab84fc622c8c19f1f to your computer and use it in GitHub Desktop.
Call multiple python classes with the same methods and function signatures.
class MultiCall():
"""This class calls all methods in multiple other class objects.
(all classes should have the same methods and arguments)
e.g.:
m=MultiCall([A(), B()])
m.msg("hi")
will result in a call to A.msg("hi") and B.msg("hi")
NOTE: I'll use this in micropython on a ESP32, so low memory usage is essential.
Current overhead is 2 extra function calls on the stack and an extra class.
"""
def __init__(self, classes):
for fname in dir(classes[0]):
methods=[]
for cls in classes:
methods.append(getattr(cls, fname))
setattr(self, fname, lambda *args,**kwargs: self.call_all(methods, args, kwargs))
def call_all(self, methods, args, kwargs):
for method in methods:
method(*args, **kwargs)
@underdarknl
Copy link

#!/usr/bin/python3
"""MultiCall mem efficient version"""
__author__ = 'Jan Klopper (jan@underdark.nl)'
__version__ = 0.1
class MultiCall():
  def __init__(self, classes):
    self.classes = classes

  def caller(self, fname, args, kwargs):
    results = []
    for c in self.classes:
      results.append(c.__getattribute__(fname)(*args, **kwargs))
    return results

  def __getattr__(self, fname):
    setattr(self, fname, lambda *args,**kwargs: self.caller(fname, args, kwargs))
    return self.__dict__[fname]

if __name__ == '__main__':
  class A(object):
    def msg(self, string):
      print('A:', string)

  class B(object):
    def msg(self, string):
      print('B:', string)

  m=MultiCall([A(), B()])
  m.msg("hi")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment