Я нашел (не идеальное, но нормальное) решение для своих проблем.
I) Поиск и запись функций, сопрограмм и т. Д. c. в файл ( работает ):
Как и подозревал @MisterMiyagi, модуль проверки - хороший способ go. Для обычных вещей можно с помощью 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) Но как насчет декорированных вещей (, кажется, работает ) ?
I) не будет работать для украшенных вещей, он просто игнорируется без исключения. Кажется, что используется from functools import wraps
. Во многих примерах декоратор @wraps
добавляется в класс декоратора. Это было невозможно для меня, но есть хороший обходной путь:
@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
Оболочки могут быть помещены над оригинальным декорированным методом / классом / функцией, и кажется, что они ведут себя так, как я хочу. Теперь мы можем добавить simple_method
в func_list
из I).
III) А как насчет импорта?
Что ж, кажется довольно сложным / невозможным на самом деле прочитать зависимости функции. Мой обходной путь - отбросить все требуемые операции импорта в класс ( sigh ). Этот класс может быть брошен в func_list
из I) и записан в файл.
РЕДАКТИРОВАТЬ: Существует более чистый способ, который может работать, после некоторой модификации, с I) и II). Модуль magi c имеет значение ast .
. Я переписал следующее:
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")
Теперь я могу проанализировать свое собственное имя сценария и заполнить файл module_file данными для импорта. и из ... import, которые он найдет при посещении всех узлов в этом дереве:
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")