Как динамически предоставлять значения аргументов функции по умолчанию из конфигурационных файлов? - PullRequest
0 голосов
/ 08 января 2019

Как задать параметры аргумента по умолчанию, динамически установленные файлом конфигурации, созданным пользователем?

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

Кто-нибудь знает, как импортировать функцию, учитывая номер строки внутри функции и файл python, содержащий функцию (включая функции внутри классов)?


РЕДАКТИРОВАТЬ (добавлен приведенный ниже вариант использования по просьбе комментариев)

Я хочу получить функцию, которая по умолчанию имеет аргумент configured_arg() в следующих примерах:

class SomeClass:

    def __init__(kwarg=configured_arg()):
        ...

def some_function(kwarg=configured_arg()):
    ...

    def another_function(kwarg=configured_arg()):
        ...

def configured_arg():
    # NOTE: `inspect.stack` returns the caller as "<module>"
    # NOTE: `inspect.stack` returns the `lineno` and file path of the call
    caller = get_caller() # Unsure of how to implement
    arg_key = get_arg_key() # Unsure of how to implement
    return fetch_configured_value(caller, arg_key) # Fetch default arg from global config

Перед публикацией на SO я пытался использовать inspect.stack. Вызывающий абонент (например, some_function) не отображается в стеке configurable_arg. Тем не менее, inspect.stack имеет lineno аргумент по умолчанию, который был объявлен. Этот опыт вдохновил текущий вопрос.

1 Ответ

0 голосов
/ 09 января 2019

Во время вызова функции configured_args функция, для которой она устанавливает аргументы по умолчанию, еще не определена.

Вам необходимо изменить аргументы по умолчанию после определения функции. Один из способов сделать это - использовать декоратор.

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

  • __module__: имя модуля, в котором определена функция;
  • __name__: название функции;
  • __qualname__: полный путь к функции в модуле. Например, функция f, определенная внутри класса A, будет иметь __qualname__, установленную в A.f.

код

from functools import wraps

def get_kwargs(qualname, module):
    # Get the default kwargs from configs
    return {'kwarg': ...}

def configure_args(f):
    qualname = f.__qualname__
    module = f.__module__

    default_kwargs = get_kwargs(qualname, module)

    @wraps(f)
    def wrapper(*args, **kwargs):
        new_kwargs = {**default_kwargs , **kwargs}
        return f(*args, **new_kwargs)

    return wrapper

@configure_args
def my_func(*args, **kwargs):
    ...

Функция my_func теперь имеет аргумент ключевого слова по умолчанию kwarg.

...