简体   繁体   English

编写带有修饰函数和导入的模块

[英]Write Module with decorated functions and imports

i have this code in a python file:我在一个python文件中有这个代码:

from dec import my_decorator
import asyncio

@my_decorator
async def simple_method(bar):  # , x, plc_name, var_name):
    print("Henlo from simple_method\npartent:{}".format(parent))
    return


@my_decorator
async def other_simple_meth(bar, value):
    print("Henlo from other_simple_meth:\t Val:{}".format(value))
    return


async def main():
    print("Start Module-Export")
    open('module_functions.py', 'a').close()
    # Write all decorated functions to modue_functions.py
    print("Functions in module_functions.py exported")
    while True:
        asyncio.sleep(2)
        print("z...z...Z...")

My goal is to write all decorated functions (inc. the import dependencies) into a second module file (here "module_functions.py").我的目标是将所有装饰函数(包括导入依赖项)写入第二个模块文件(此处为“module_functions.py”)。 My 'module_functions.py' file should look like this:我的“module_functions.py”文件应该是这样的:

from dec import my_decorator
import asyncio

@my_decorator
async def simple_method(bar):  # , x, plc_name, var_name):
    print("Henlo from simple_method\npartent:{}".format(parent))
    return


@my_decorator
async def other_simple_meth(bar, value):
    print("Henlo from other_simple_meth:\t Val:{}".format(value))
    return

I know how to get references and names of a function, but not how to "copy/paste" the functioncode (incl. decorator and all dependencies) into a seperated file.我知道如何获取函数的引用和名称,但不知道如何将函数代码(包括装饰器和所有依赖项)“复制/粘贴”到一个单独的文件中。 Is this even possible?这甚至可能吗?

EDIT : I know that pickle and dill exist, but this may not fullfill the goal.编辑:我知道存在泡菜和莳萝,但这可能无法实现目标。 The problem is, that someone else may not know the order of the dumped file and loading them back may/will cause problem.问题是,其他人可能不知道转储文件的顺序并且将它们加载回来可能/会导致问题。 As well it seems to be not possible to edit such loaded functions again.同样,似乎无法再次编辑此类加载的函数。

I found a (not ideal, but ok) solution for my problems.我为我的问题找到了一个(不理想,但很好)的解决方案。

I) Find and write functions, coroutines etc. into a file ( works ): I) 查找函数、协程等并将其写入文件(作品):

Like @MisterMiyagi suspected, is the inspect module a good way to go.就像怀疑的@MisterMiyagi 一样,检查模块是一个好方法。 For the common stuff, it is possible with inspect.getsource() to get the code and write them into a file:对于常见的东西,可以使用inspect.getsource()获取代码并将它们写入文件:

# List of wanted stuff    
func_list = [simple_method, meth_with_input, meth_with_input_and_output, func_myself] 

    with open('module_functions.py', 'a') as module_file:
        for func in func_list:
            try:
                module_file.write(inspect.getsource(func))
                module_file.write("\n")
            except:
                print("Error :( ")

II) But what about decorated stuff( seems to work )? II)但是装饰的东西(似乎有效)呢?

I) will not work for decorated stuff, it is just ignored without throwing an exception. I) 不适用于装饰的东西,它只是被忽略而不抛出异常。 What seems to be used is from functools import wraps .似乎使用的是from functools import wraps In many examples the @wraps decorator is added into the decorator class.在许多示例中, @wraps装饰器被添加到装饰器类中。 This was not possible for me, but there is a good workaround:这对我来说是不可能的,但有一个很好的解决方法:

@wraps(lambda: simple_method) #<---add wraps-decorator here
@my_decorator
async def simple_method(parent):  # , x, plc_name, var_name):
    print("Henlo from simple_method\npartent:{}".format(parent))
    return

Wraps can be placed above the original decorated method/class/function and it seems to behave like I want. Wraps 可以放在原始装饰的方法/类/函数之上,它似乎表现得像我想要的。 Now we can add simple_method into the func_list of I).现在我们可以将simple_method添加到 I) 的func_list中。

III) What about the imports? III) 进口情况如何?

Well it seems to be quite tricky/impossible to actually read the dependencies of a function.好吧,实际读取函数的依赖项似乎非常棘手/不可能。 My workaround is to drop all wanted imports into a class ( sigh ).我的解决方法是将所有需要的导入放入一个类中(叹气)。 This class can be throw into the func_list of I) and is written into the file.这个类可以扔到I)的func_list中写入文件。

EDIT: There is a cleaner way, which may works, after some modification, with I) and II) as well.编辑:有一种更干净的方法,经过一些修改后,它也可能适用于 I) 和 II)。 The magic module is ast .魔法模块是ast

I have overwritten following:我已经覆盖了以下内容:

class ImportVisitor(ast.NodeVisitor):

    def __init__(self, target):
        super().__init__()
        self.file_target = target

    "pick these special nodes via overwriting: visit_classname." \
    "classnames are listed in https://docs.python.org/3.6/library/ast.html#abstract-grammar"
    def visit_Import(self, node):
        "Overwrite func!"
        "Write all statements just with import like -  import ast into file_target"
        str = 'import '+', '.join(alias.name for alias in node.names)
        self.file_target.write(str+"\n")

    def visit_ImportFrom(self, node):
        "Overwrite func!"
        "Write all statements with from ... import (like - from os.path import basename) into file_tagrget"
        str = 'from '+ node.module+ ' import '+', '.join(alias.name for alias in node.names)
        self.file_target.write(str+"\n")

Now I can parse my own script name and fill the module_file with the imports and from...imports it will find while visiting all nodes in this tree:现在我可以解析我自己的脚本名称并使用导入和 from...imports 填充 module_file 它将在访问此树中的所有节点时找到:

    with open('module_functions.py', 'a') as module_file:
        with open(basename(__file__), "rb") as f:
            tree = ast.parse(f.read(), basename(__file__))
            visitor = ImportVisitor(module_file)
            visitor.visit(tree)
            module_file.write("\n\n")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM