Extracting code to localize it in a callback

This is my first post, so please let me know if I do it wrong. I tried to find an existing answer, but was not sure what to look for.

Consider the following simple example: a python module named mymath.py that uses only built-in operations and python modules. This custom module is portable, so anyone can execute code without installing any other than python.

 # mymath.py import sys def minus(a, b): return ab def mult(a, b): return a*b def div(a, b): return a/b def plus(a, b): return a+b def sum_series(int_list): sum = 0 for i in int_list: sum = plus(sum, i) return sum def main(): my_list = [2, 4, 6] value = sum_series(my_list) sys.stdout.write("your list total = {}".format(value)) 

Note that main() only calls sum_series() , which in turn calls plus() . Other functions may be required elsewhere in this fictitious code base, but we are only concerned about main() .

Now I would like to copy only the corresponding source code into another object as a text string. In other words, compile main() and all its dependencies (recursively), resulting in a line of executable code.

My current solution:

 import inspect import mymath # copy the source code in to the callback source = inspect.getsource(mymath) # then append a call to the main function source += "\nmain()" 

This works by creating a local copy of the module as a string that can run main() without requiring import of mymath . The problem is that knob now bloated with all the extra unused functions, although it is able to pick up any changes I make for mymath.py , reusing my current solution.

So the question is is there a way to make an equivalent:

 source = getFunctionSourcerRecursively(mymath.main) source += "\nmain()" 

whereby source =

 # mymath.py import sys def plus(a, b): return a+b def sum_series(int_list): sum = 0 for i in int_list: sum = plus(sum, i) return sum def main(): my_list = [2, 4, 6] sys.stdout.write("your list total = {}".format(sum_series(my_list))) main() 

Thus, basically the “source” now contains only the corresponding code and is portable, without requiring people outside my site to install mymath.

If you're interested, in my real case, I use the Foundry Nuke application (the build application), which has an internal callback system that can run code when callback events are knob on knob (property). I want to be able to share these saved Nuke files ( .nk or .nknc ) with remote clients, without requiring them to modify their system.

+5
source share
1 answer

You can try informal interfaces (aka protocols). While protocols work fine in many cases, there are situations where informal interfaces or duck typing in general can cause confusion. For example, Addition and Multiplication are both mathFunc() . But this is not the same thing, even if they implement the same interfaces / protocols. Abstract base classes or ABCs can help solve this problem.

The concept of ABC is simple: the user defines base classes that are abstract in nature. We define certain methods on base classes as abstract methods. Therefore, any objects originating from these base classes are forced to implement these methods. And since they used base classes, if we see that an object has our class as a base class, we can say that this object implements an interface. Now we can use types to determine if an object implements a specific interface.

 import mymath class MathClass(mymath.ABC): @mymath.abstractmethod def mathFunc(self): pass 
0
source

Source: https://habr.com/ru/post/1268881/


All Articles