python 非标准可选参数默认值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1118454/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:32:08  来源:igfitidea点击:

Non-Standard Optional Argument Defaults

pythonoptional-arguments

提问by ooboo

I have two functions:

我有两个功能:

def f(a,b,c=g(b)):
    blabla

def g(n):
    blabla

cis an optional argument in function f. If the user does not specify its value, the program should compute g(b) and that would be the value of c. But the code does not compile - it says name 'b' is not defined. How to fix that?

c是 function 中的一个可选参数f。如果用户没有指定它的值,程序应该计算 g(b),这就是 的值c。但是代码没有编译——它说名称“b”没有定义。如何解决?

Someone suggested:

有人建议:

def g(b):
    blabla

def f(a,b,c=None):
    if c is None:
        c = g(b)
    blabla

But this doesn't work. Maybe the user intended cto be None and then cwill have another value.

但这不起作用。也许用户打算c成为 None ,然后c会有另一个值。

回答by Paolo Bergantino

def f(a,b,c=None):
    if c is None:
        c = g(b)

If Nonecan be a valid value for cthen you do this:

如果None可以是一个有效值,c那么你可以这样做:

sentinel = object()
def f(a,b,c=sentinel):
    if c is sentinel:
        c = g(b)

回答by codeape

You cannot do it that way.

你不能那样做。

Inside the function, check if c is specified. If not, do the calculation.

在函数内部,检查是否指定了 c。如果不是,请进行计算。

def f(a,b,c=None):
    if c == None:
        c = g(b)
    blabla

回答by SilentGhost

value of cwill be evaluated (g(b)) at compilation time. You need gdefined before ftherefore. And of course you need a global bvariable to be defined at that stage too.

的值cg(b)在编译时评估 ( )。因此,您需要g事先定义f。当然,您还需要b在该阶段定义一个全局变量。

b = 4

def g(a):
    return a+1

def test(a, c=g(b)):
    print(c)

test(b)

prints 5.

打印 5.

回答by Thomas 'PointedEars' Lahn

The problem with

问题与

sentinel = object()
def f(a, b, c=sentinel):
  if c is sentinel:
    c = g(b)

is that sentinelis global/public unless this code is part of a function/method. So someone might still be able to call f(23, 42, sentinel). However, if fis global/public, you can use a closure to make sentinellocal/private so that the caller cannot use it:

sentinel全局/公共的,除非此代码是函数/方法的一部分。所以有人可能仍然可以打电话f(23, 42, sentinel)。但是,如果f是 global/public,则可以使用闭包使sentinellocal/private 使调用者无法使用它:

def f():
  sentinel = object()
  def tmp(a, b, c=sentinel):
    if c is sentinel:
      c = g(b)
  return tmp
f = f()

If you are concerned that static code analyzers could get the wrong idea about fthen, you can use the same parameters for the factory:

如果您担心静态代码分析器可能会对此产生错误的想法f,您可以对工厂使用相同的参数:

def f(a, b, c=object()): #@UnusedVariable
  sentinel = object()
  def tmp(a, b, c=sentinel):
    if c is sentinel:
      c = g(b)
  return tmp
f = f(23, 42)

回答by Maiku Mori

def f(a,b,*args):
    if len(args) == 1:
        c = args[0]
    elif len(args) == 0:
        c = g(b)
    else:
        raise Exception('Function takes 2 or 3 parameters only.')
    blabla

def g(n):
    blabla

You can probably structure it better, but that's the main idea. Alternatively you can use **kwargsand use the function like f(a,b,c=Something), you just have to modify faccordingly.

您可能可以更好地构建它,但这是主要思想。或者,您可以使用**kwargs和使用类似的功能f(a,b,c=Something),您只需要相应地进行修改f

Documentation

文档