Лучший способ передать функцию, указанную в файле x в качестве параметра командной строки, в файл y в python - PullRequest
1 голос
/ 25 октября 2019

Я пишу оболочку или конвейер для создания набора данных tfrecords, в который я хотел бы предоставить функцию для применения к набору данных.

Я бы хотел, чтобы пользователь мог внедритьФункция определена в другом файле Python, который вызывается в моем скрипте для преобразования данных.

Почему? Единственное, что нужно сделать пользователю, это написать функцию, которая приводит его данные в правильный формат, а существующий код сделает все остальное.

Я знаю, что я мог бы попросить пользователя написатьфункция в том же файле и вызвать его, или иметь оператор импорта и т. д.

Так что в качестве минимального примера я хотел бы иметь файл y.py

def main(argv):
    # Parse args etc, let's assume it is there.

    dataset = tf.data.TFRecordDataset(args.filename)
    dataset = dataset.map(args.function)
    # Continue with doing stuff that is independent from actual content

Так что яхотелось бы иметь возможность сделать что-то вроде этого

    python y.py --func x.py my_func

и использовать функцию, определенную в x.py my_func в dataset.map (...)

Есть ли способсделать это в Python, и если да, какой лучший способ сделать это?

Ответы [ 2 ]

1 голос
/ 25 октября 2019
  1. Передать имя файла в качестве аргумента в ваш скрипт (и имя функции)
  2. Считать файл в строку, возможно извлекая данную функцию
  3. , использовать Python exec () для выполнения кода

Пример:

file = "def fun(*args): \n  return args"
func = "fun(1,2,3)"

def execute(func, file):
    program = file + "\nresult = " + func
    local = {}
    exec(program, local)
    return local['result']

r = execute(func, file)
print(r) 

Аналогично здесь однако мы должны использовать locals() какмы не вызываем exec в глобальной области видимости.

Примечание: использование exec несколько опасно, вы должны быть уверены, что функция безопасна - если вы ее используете, то это нормально!

Надеюсь, это поможет.

0 голосов
/ 25 октября 2019

Хорошо, поэтому я сам составил ответ, используя информацию из комментариев и этот ответ .

    import importlib, inspect, sys, os
    # path is given path to file, funcion_name is name of function and args are the function arguments

    # Create package and module name from path
    package = os.path.dirname(path).replace(os.path.sep,'.')
    module_name = os.path.basename(path).split('.')[0]

    # Import module and get members
    module = importlib.import_module(module_name, package)
    members = inspect.getmembers(module)

    # Find matching function
    function = [t[1] for t in members if t[0] == function_name][0]
    function(args)

Это точно решает вопрос, так как я получаю вызываемый функциональный объект, которыйЯ могу вызывать, передавать, использовать как обычную функцию.

...