Created
July 3, 2015 13:41
-
-
Save tai/dbd2ae1722c477d9c2fd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| A skelton code of a framework that wraps user function | |
| without any modification. This makes framework really | |
| transparent and help keeping user's code clean. | |
| The problem is that once user function gets enhanced | |
| and needs some framework-dependent info (like processing | |
| context), it is hard to pass it down. Hence this code to | |
| solve the problem. | |
| This framework "sandwitches" a user function in following manner: | |
| [framework] callfunc() | |
| -> [user] userfunc() | |
| -> [framework] get_context() | |
| Whenever userfunc needs some extra framework data, | |
| it can call get_context() API to obtain one. | |
| With a help of yield call, get_context() obtains | |
| data in callfunc() namespace and returns it to userfunc. | |
| It'd be perfect if Python can hide a yield call needed | |
| in userfunc with some meta-programming, but it seems | |
| current Python does not have that capability. | |
| """ | |
| # request id used by inter-framework protocol | |
| GET_CONTEXT = 1 | |
| def frameworkapi(func): | |
| """Decorates user function so it can be embedded in the framework""" | |
| return func | |
| @frameworkapi | |
| def userfunc(a, b, c): | |
| """user function to be wrapped by this framework""" | |
| # obtain extra data from side-channel (= over yield call) | |
| ctx = yield from get_context() | |
| print("userfunc: ctx=" + str(ctx)) | |
| return a + b + c | |
| def callfunc(func, *args): | |
| """Calls user function, with a side-channel to exchange extra data""" | |
| ctx = "some extra framework context" | |
| gen = func(*args) | |
| # inter-framework protocol handler | |
| try: | |
| yield_ret = None | |
| while True: | |
| yield_arg = gen.send(yield_ret) | |
| yield_ret = None | |
| if yield_arg == GET_CONTEXT: | |
| yield_ret = ctx | |
| except StopIteration as func_ret: | |
| return func_ret.value | |
| def get_context(): | |
| ret = yield GET_CONTEXT | |
| return ret | |
| ret = callfunc(userfunc, 1, 2, 3) | |
| print("userfunc: ret=%s" % str(ret)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment