简体   繁体   English

如何将附加参数(除了参数)传递给 Python 中的函数

[英]How to pass additional parameters (besides of arguments) to a function in Python

I need to write a function (say fun1 ) that has one argument, because it will be used in other function ( fun2 ).我需要编写一个具有一个参数的函数(比如fun1 ),因为它将在其他函数( fun2 )中使用。 The latter requires a function with a single argument.后者需要一个带有单个参数的函数。 However, I need to pass other parameters to function fun1 .但是,我需要将其他参数传递给函数fun1 How can I do this in Python without using global variables?如何在不使用全局变量的情况下在 Python 中执行此操作? Or this is the only way?或者这是唯一的方法?

Addition: If it is important, fun2 is some optimization function from scipy.optimize .补充:如果很重要, fun2scipy.optimize一些优化函数。 Below is an example of passing additional parameter c to function fun1 using global .下面是使用global将附加参数c传递给函数fun1的示例。 In the first call, function fun2 takes fun1 as x+1 , but in the second call, fun1 is x+2 .在第一次调用中,函数fun2fun1作为x+1 ,但在第二次调用中, fun1x+2 I would like to make similar, but without using global .我想做类似的,但不使用global Hopefully, the example clarifies the question.希望这个例子可以澄清这个问题。 (The example is changed). (示例已更改)。

def fun1(x) :
   global c
   return  x + c

def fun2(f1, x) :
   return  f1(x)

# main program
global c
x0= 1  
c= 1;   y= fun2(fun1, x0);  print(y)    # gives 2
c= 2;   y= fun2(fun1, x0);  print(y)    # gives 3

If I've understood your question correctly, there are quite a number of ways to do what you want and avoid using global variables.如果我正确理解了您的问题,那么有很多方法可以做您想做的事情并避免使用全局变量。 Here they are.他们来了。

Given:鉴于:

x0 = 1
def fun2(f1, x):
    return f1(x)

All of these techniques accomplish your goal:所有这些技术都可以实现您的目标:

#### #0 -- function attributes
def fun1(x):
    return x + fun1.c

fun1.c = 1;  y = fun2(fun1, x0);   print(y)   # --> 2
fun1.c = 2;  y = fun2(fun1, x0);   print(y)   # --> 3

#### #1 -- closure
def fun1(c):
    def wrapper(x):
        return x + c
    return wrapper

y = fun2(fun1(c=1), x0);   print(y)   # --> 2
y = fun2(fun1(c=2), x0);   print(y)   # --> 3

#### #2 -- functools.partial object
from functools import partial

def fun1(x, c):
    return x + c

y = fun2(partial(fun1, c=1), x0);   print(y)   # --> 2
y = fun2(partial(fun1, c=2), x0);   print(y)   # --> 3

#### #3 -- function object (functor)
class Fun1(object):
    def __init__(self, c):
        self.c = c
    def __call__(self, x):
        return x + self.c

y = fun2(Fun1(c=1), x0);   print(y)   # --> 2
y = fun2(Fun1(c=2), x0);   print(y)   # --> 3

#### #4 -- function decorator
def fun1(x, c):
    return x + c

def decorate(c):
    def wrapper(f):
        def wrapped(x):
            return f(x, c)
        return wrapped
    return wrapper

y = fun2(decorate(c=1)(fun1), x0);   print(y)   # --> 2
y = fun2(decorate(c=2)(fun1), x0);   print(y)   # --> 3

Note that writing c= arguments wasn't always strictly required in the calls -- I just put it in all of the usage examples for consistency and because it makes it clearer how it's being passed.请注意,在调用中并不总是严格要求编写c=参数——我只是将它放在所有使用示例中以保持一致性,因为它可以更清楚地说明它是如何传递的。

The fact that that function can be called even without those other parameters suggests, that they are optional and have some default value.即使没有那些其他参数也可以调用该函数的事实表明,它们是可选的并且具有一些默认值。 So you should use default arguments .所以你应该使用默认参数

def fun1(foo, bar='baz'):
    # do something

This way you can call function fun1('hi') and bar will default to 'baz' .这样你就可以调用函数fun1('hi')并且bar将默认为'baz' You can also call it fun1('hi', 15) .你也可以称之为fun1('hi', 15)

If they don't have any reasonable default, you can use None as the default value instead.如果它们没有任何合理的默认值,您可以使用None作为默认值。

def fun1(foo, bar=None):
    if bar is None:
        # `bar` argument was not provided
    else:
        # it was provided

What you are looking for is a method in a class.您正在寻找的是类中的方法。

you define a class, with a method fun1 and an instance variable c .你定义了一个类,有一个方法 fun1 和一个实例变量c it is accessed from anywhere using the .它可以从任何地方使用. notation:符号:

class A:
    def fun1(self, x):
        return x + self.c

Let's define fun2, for the example:让我们定义 fun2,例如:

def fun2(f, p):
    return f(p)

We can now use ac it like you did with the global varaible c :我们现在可以像使用全局变量c一样使用ac

>>> a = A() # create an instance and initialize it
>>>         # "self.c" is undefined yet
>>>
>>> a.c = 1 # "self.c" will be 1
>>> fun2(a.fun1, 1)
2
>>> a.c = 2 # now "self.c" will be 2
>>> fun2(a.fun1, 1) # same arguments, different result
3

Here you can learn more about classes. 在这里,您可以了解有关课程的更多信息。

Just add the extra parameters with default values:只需添加具有默认值的额外参数:

def fun1(param1, param2=None, param3=None):
    ...

Then you can call fun1 from fun2 like this:然后你可以像这样从fun2调用fun1

def fun2():
    something = fun1(42)

And from somewhere else you can call it like this:从其他地方你可以这样称呼它:

fun1(42, param2=60)

You may use the decorators to pass it the very decorators:您可以使用装饰器将装饰器传递给它:

def jwt_or_redirect(fn):
  @wraps(fn)
  def decorator(*args, **kwargs):
    ...
    return fn(*args, **kwargs)
  return decorator

def jwt_refresh(fn):
  @wraps(fn)
  def decorator(*args, **kwargs):
    ...
    new_kwargs = {'refreshed_jwt': 'xxxxx-xxxxxx'}
    new_kwargs.update(kwargs)
    return fn(*args, **new_kwargs)
  return decorator

and the final function:和最后的功能:

@jwt_or_redirect
@jwt_refresh
def home_page(*args, **kwargs):
  return kwargs['refreched_jwt']

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

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