2

我需要编写一个fun1具有一个参数的函数(比如 ),因为它将在其他函数(fun2)中使用。后者需要一个带有单个参数的函数。但是,我需要将其他参数传递给 function fun1。如何在不使用全局变量的情况下在 Python 中执行此操作?或者这是唯一的方法?

补充:如果很重要,fun2是一些优化功能scipy.optimize。下面是一个使用 将附加参数传递c给函数fun1的示例global。在第一次调用中,函数fun2采用fun1as x+1,但在第二次调用中,fun1is x+2。我想做类似的,但不使用global. 希望这个例子能澄清这个问题。(示例已更改)。

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
4

5 回答 5

4

如果我正确理解了您的问题,那么有很多方法可以做您想做的事情并避免使用全局变量。他们来了。

鉴于:

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

所有这些技术都可以实现您的目标:

#### #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

请注意,c=在调用中并不总是严格要求编写参数——为了保持一致性,我只是将它放在所有用法示例中,因为它可以更清楚地说明它是如何传递的。

于 2013-06-07T16:09:56.063 回答
2

即使没有其他参数也可以调用该函数这一事实表明,它们是可选的并且具有一些默认值。所以你应该使用默认参数

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

这样您就可以调用函数fun1('hi')并将bar默认为'baz'. 你也可以调用它fun1('hi', 15)

如果它们没有任何合理None的默认值,您可以改为使用默认值。

def fun1(foo, bar=None):
    if bar is None:
        # `bar` argument was not provided
    else:
        # it was provided
于 2013-06-07T12:18:15.887 回答
2

您正在寻找的是类中的方法。

你定义了一个类,有一个方法 fun1 和一个实例变量c。可以使用以下.符号从任何地方访问它:

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

让我们定义 fun2,例如:

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

我们现在a.c可以像使用全局变量一样使用它c

>>> 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

在这里,您可以了解有关课程的更多信息。

于 2013-06-07T12:50:45.173 回答
1

只需添加具有默认值的额外参数:

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

然后你可以这样调用fun1fun2

def fun2():
    something = fun1(42)

从其他地方你可以这样称呼它:

fun1(42, param2=60)
于 2013-06-07T12:18:44.373 回答
0

您可以使用装饰器将装饰器传递给它:

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

和最终功能:

@jwt_or_redirect
@jwt_refresh
def home_page(*args, **kwargs):
  return kwargs['refreched_jwt']
于 2021-04-24T21:46:00.173 回答