I'm implementing a template method design pattern in python, and have a question about whether a helper function in the abstract class' template method should be an instance or static function. Both would work, but I'm not sure on the pros and cons of both approaches.
Background
I'm writing a framework to support testing images, where I can plugin different test methods depending on the type of image etc, hence I'm using a template method design pattern.
The abstract class template method to do the testing will need to support testing images in parallel, and will support doing this either using Multiprocessing (if running locally) or via AWS lambdas if running on AWS.
I want to encapsulate the details of the 'run_tests_locally' and the 'run_tests_lambda' into helper functions to avoid cluttering the main template method.
Question
My question is whether it's best to make the above 'run_tests' functions as A) instance methods, or B) static methods in my abstract class definition. ...See below
Both would seem to work, but not sure which is best, and would love some guidance/thoughts
from abc import ABC, abstractmethod
import util.misc as misc
class TestFramework(ABC):
"""
Abstract class for executing tests
"""
@abstractmethod
def filter(self, objs):
"""Take list of objects, and return filtered list of those to test"""
pass
@abstractmethod
def do_test(self, obj):
"""Take a single object, test it, and return dict of results"""
pass
def execute_test(self, file_list):
"""Execute test"""
# library function
all_objs = misc.load_files(file_list)
# instance template function - shortlist objects
to_test_objs = self.filter(all_objs)
# now test objects
# how is it best to implment the 'run_tests' functions?
# A) instance methods?
# B) static methods?
# if running on aws, do tests across multiple lambda
# if local, use MP to run in parallel
if env = 'aws':
# as an instance method
test_results = self.run_tests_lambda(to_test_objs)
# as static:
test_results = run_tests_lambda_STATIC(to_test_objs, self.do_test)
else:
# instance form:
test_results = self.run_tests_local(to_test_objs)
# static form:
test_results = run_tests_local_STATIC(to_test_objs, self.do_test)
return test_results
# instance method implementation
def run_tests_local(self, to_test_objs):
all_results = {}
with ProcessPoolExecutor as e:
procs = [e.submit(self.do_test, obj) for obj in to_test_objs]
for proc in as_completed(procs):
all_results.update(proc.result())
return all_results
# static method implementation
@staticmethod
def run_tests_local_STATIC(to_test_objs, test_fn):
all_results = {}
with ProcessPoolExecutor as e:
procs = [e.submit(test_fn, obj) for obj in to_test_objs]
for proc in as_completed(procs):
all_results.update(proc.result())
return all_results
Aucun commentaire:
Enregistrer un commentaire