Передача аргументов в функцию Python внутри функции - PullRequest
0 голосов
/ 23 апреля 2019

В случае, показанном ниже, у меня есть функция под названием func1(), которая находится в func3(), где func3() определяет значение ОДУ с использованием метода Эйлера.

def func1(x, y):
    return y * np.log(y) / x

def func3(x, y, step_size, func):
    dydx = func(x, y)
    new_x = x + step_size
    new_y = y _ step_size * dydx
    return new_x, new_y

step_size - 0.1
lower = 2.0
upper = 3.0
e = 2.7182828284

x_val = [2.0]
y_val = [e]
for i in range(10):
    x, y = func3(x_val[i], y_val[i], step_size, func1)
    x_val.append(x)
    y_val.append(y)

код передает func1 в func3 в качестве декоратора и записывает вывод в список, поскольку он повторяется в диапазоне от 0 до 10. Однако код внутри func3() жестко закодирован для точного ввода func1(), то есть x и y.Я хотел бы написать func3(), чтобы он был достаточно универсальным, чтобы вы могли передать ему любую функцию, если ее первые два входа - x и y, но это должно быть как можно больше входных данных.Итак, предположим, что весь код, показанный выше, был идентичен, но вместо передачи func1() я передал func2() в func3() со структурой ниже.

def func2(x, y, z):
    return z * y * np.log(y) / (x*z)

Как я мог написать func3() чтобы быть достаточно универсальным, чтобы он мог принять любую из двух функций и понять, что их больше аргументов для передачи func1(), что также должно быть передано в func3()?

Ответы [ 4 ]

1 голос
/ 23 апреля 2019

Вы можете использовать синтаксис аргументов переменной длины в Python, чтобы ожидать любые дополнительные аргументы и передавать их дальше.Если их нет, то все равно работает: помеченная переменная получит пустой список в качестве значения и исчезнет при расширении осенью до func.

def func1(x, y):
    return x+y

def func2(x, y, z):
    return (x+y)*z

def caller(func, x, y, other, other2, *args):
    return func(x, y, *args)
0 голосов
/ 23 апреля 2019

Не думаю, что вам действительно нужно принимать другие аргументы, кроме x и y, или менять func3.

Предположим, вы хотите передать z внутренней функции.И вам нужно также передать его в func3.Поскольку z не изменится во время вызова func3, вы можете просто сделать что-то вроде func3(x, y, lambda x, y : your_func (x, y , z), step) и использовать функции с любым количеством аргументов через лямбду, которая принимает x и y.

В вашем случае вызов будет выглядеть так:

x, y = func3(x_val[i], y_val[i], step_size, lambda x, y: func2(x, y, 111))
0 голосов
/ 23 апреля 2019

Было бы лучше использовать * args и ** kargs (** kwargs в определениях функций в python используется для передачи ключевого слова, списка аргументов переменной длины. Мы используем имя kwargs с двойной звездой. Причина в том, чтопотому что двойная звезда позволяет нам проходить через ключевые аргументы и любое их количество).

Например:

def myFun (arg1, arg2, arg3):

print("arg1:", arg1) 

print("arg2:", arg2) 

print("arg3:", arg3) 

args = ("Привет", "привет", "пока")

myFun (* args)

kwargs = {"arg1": "Geek", "arg2": "Nerd "," arg3 ":" Noob "}

myFun (** kwargs)

Вывод: Привет, привет пока Geek Nerd Noob

0 голосов
/ 23 апреля 2019

Используйте *args и **kwargs для сбора аргументов (в дополнение к x и y, предназначенным для вашего обратного вызова):

def func3(x, y, step_size, func, *args, **kwargs):
    dydx = func(x, y, *args, **kwargs)
    ...

Однако, подумайте, действительно ли это необходимо для func3 позвонить func себе;пусть звонящий сделает это вместо этого.

def func3(x, y, step_size, dydx):
    new_x = x + step_size
    new_y = y - step_size * dydx
    return new_x, new_y

for old_x, old_y in zip(x_val, y_val):
    x, y = func3(old_x, old_y, step_size, func1(x, y))
    ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...