Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
return
#4
I have a solution using a function object type from my personal library, the below class 'algorithm'
# algorithm/__init__.py
__version__ = '2019.06.18'

from functools import partial, singledispatch
import types

#========================================
# Obtention de la documentation
#========================================

def doctopic_assembly():
    """Returns a assembly of documentation topics for this module"""
    from .doc.main import doctopic_assembly
    return doctopic_assembly()

_property = property

@singledispatch
def property(func):
    return _property(func)

class algorithm_meta(type):
    def __new__(meta, class_name, bases, new_attrs):
        cls = type.__new__(meta, class_name, bases, new_attrs)
        return cls
    
    def __call__(cls, *args, **kwargs):
        instance = cls.__new__(cls)
        instance.kwargs = kwargs
        instance.__dict__.update(kwargs)
        return instance.run(*args)
        #try:
            #return instance.run(*args)
        #except TypeError:
            #print(instance, args)
            #raise

    def __get__(cls, obj, objtype=None):
        # This allows to use the algoritm type as a method
        if obj is None:
            return cls
        return partial(_algorithm_as_method, cls, obj)
    
    property = staticmethod(property)
    
def _algorithm_as_method(cls, obj, *args, **kwargs):
    instance = cls.__new__(cls)
    instance.o = obj
    instance.kwargs = kwargs
    instance.__dict__.update(kwargs)
    return instance.run(*args)

@property.register(algorithm_meta)
def _(cls):
    return _property(partial(_algorithm_as_method, cls))

class algorithm(metaclass=algorithm_meta):
    def run(self, *args):
        return self
To implement the desired behaviour, I now define a subclass 'returnable' of 'algorithm', then I'm ready to implement your tasks B() and A(). Look at the code starting from 'class B(returnable)'
# paillasse/pf/deepreturn.py - example code
from algorithm import algorithm

class Return(Exception):
    pass

class returnable(algorithm):
    def run(self, *args):
        try:
            return self.main(*args)
        except Return as exc:
            if exc.args[0] is self:
                return exc.args[1]
            else:
                raise
    
    def return_(self, value=None):
        raise Return(self, value)

class B(returnable):
    def main(self, x):
        self.subtask0(x)
        self.subtask1(x)
    
    def subtask0(self, x):
        if x == 0:
            self.return_('Hello!')
            
    def subtask1(self, x):
        if x == 1:
            self.return_('World!')
            
def A():
    print(B(0))
    print(B(1))
    print(B(2))
    
if __name__ == '__main__':
    A()
My output
Output:
λ python paillasse/pf/deepreturn.py Hello! World! None
By the way, it seems that the ability to return from any subtask is a nice improvement of the algorithm class. I'm considering incorporating this feature in the library. The main drawback I see is that the code is less explicit because something that looks like a function call may actually be a return statement.
Reply


Messages In This Thread
return - by Skaperen - Apr-17-2021, 11:04 PM
RE: return - by Gribouillis - Apr-21-2021, 09:26 AM
RE: return - by Skaperen - Apr-23-2021, 06:20 PM
RE: return - by Gribouillis - Apr-25-2021, 07:28 AM
RE: return - by Skaperen - Apr-25-2021, 05:49 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020