You can define a simple function at the module level and a static method. This preserves the syntax functions of invocation, introspection, and inheritance of the static method, while avoiding etching problems:
def aux(): return "VoG - Sucess" class VariabilityOfGradients(object): aux = staticmethod(aux)
For example,
import copy_reg import types from itertools import product import multiprocessing as mp def _pickle_method(method): """ Author: Steven Bethard (author of argparse) http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods """ func_name = method.im_func.__name__ obj = method.im_self cls = method.im_class cls_name = '' if func_name.startswith('__') and not func_name.endswith('__'): cls_name = cls.__name__.lstrip('_') if cls_name: func_name = '_' + cls_name + func_name return _unpickle_method, (func_name, obj, cls) def _unpickle_method(func_name, obj, cls): """ Author: Steven Bethard http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods """ for cls in cls.mro(): try: func = cls.__dict__[func_name] except KeyError: pass else: break return func.__get__(obj, cls) copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method) class ImageData(object): def __init__(self, width=60, height=60): self.width = width self.height = height self.data = [] for i in range(width): self.data.append([0] * height) def shepard_interpolation(self, seeds=20): print "ImD - Success" def aux(): return "VoG - Sucess" class VariabilityOfGradients(object): aux = staticmethod(aux) @staticmethod def calculate_orientation_uncertainty(): pool = mp.Pool() results = [] for x, y in product(range(1, 5), range(1, 5)):
gives
ImD - Success ImD - Success ImD - Success ['VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess', 'VoG - Sucess']
By the way, result.get () blocks the calling process until the function called pool.apply_async (for example, ImageData.shepard_interpolation ). So
for _ in range(3): result = pool.apply_async(ImageData.shepard_interpolation, args=[ImageData()]) results.append(result.get())
does call ImageData.shepard_interpolation sequentially, violating the purpose of the pool.
You can use instead
for _ in range(3): pool.apply_async(ImageData.shepard_interpolation, args=[ImageData()], callback=results.append)
A callback function (e.g. results.append ) is called in the thread of the calling process when the function is completed. It is sent one argument - the return value of the function. Thus, nothing blocks the execution of three calls to pool.apply_async , and the work performed by three calls to ImageData.shepard_interpolation will be performed simultaneously.
Alternatively, it is easiest to use pool.map here.
results = pool.map(ImageData.shepard_interpolation, [ImageData()]*3)