Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 非标准可选参数默认值_Python_Optional Arguments - Fatal编程技术网

Python 非标准可选参数默认值

Python 非标准可选参数默认值,python,optional-arguments,Python,Optional Arguments,我有两个职能: def f(a,b,c=g(b)): blabla def g(n): blabla c是函数f中的可选参数。如果用户未指定其值,程序应计算g(b),这将是c的值。但是代码没有编译——它说没有定义名称“b”。如何解决这个问题 有人建议: def g(b): blabla def f(a,b,c=None): if c is None: c = g(b) blabla 但这不起作用。可能用户希望c为无,然后c将有另一个

我有两个职能:

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

def g(n):
    blabla
c
是函数
f
中的可选参数。如果用户未指定其值,程序应计算g(b),这将是
c
的值。但是代码没有编译——它说没有定义名称“b”。如何解决这个问题

有人建议:

def g(b):
    blabla

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

但这不起作用。可能用户希望
c
为无,然后
c
将有另一个值。

将在编译时评估
c
的值(
g(b)
)。因此,您需要在
f
之前定义
g
。当然,您也需要在该阶段定义一个全局
b
变量

b = 4

def g(a):
    return a+1

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

test(b)

打印5张。

你不能那样做

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

def f(a,b,c=None):
    if c == None:
        c = g(b)
    blabla
如果
None
可以是
c
的有效值,则执行以下操作:

sentinel = object()
def f(a,b,c=sentinel):
    if c is sentinel:
        c = g(b)
你也许可以把它组织得更好,但这是主要的想法。或者,您可以使用
**kwargs
并使用类似
f(a,b,c=Something)
的函数,您只需相应地修改
f

问题在于

sentinel = object()
def f(a, b, c=sentinel):
  if c is sentinel:
    c = g(b)
除非此代码是函数/方法的一部分,否则
sentinel
是全局/公共的。所以有人可能仍然能够调用
f(23,42,哨兵)
。但是,如果
f
是全局/公共的,则可以使用闭包使
sentinel
成为本地/私有的,以便调用者无法使用它:

def f():
  sentinel = object()
  def tmp(a, b, c=sentinel):
    if c is sentinel:
      c = g(b)
  return tmp
f = f()
如果您担心静态代码分析器可能会对
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)


c is None比c==None快的确,“is None”比“==None”快,但更重要的原因是它更健壮。可以重写相等运算符,以便非“无”的对象仍可以比较为“等于无”。对于None的正确测试在comp.lang.python上一直存在争议。除非你真的知道自己在做什么,否则就用“是”。嘿,保罗。你能解释为什么c=None比c=None快吗?这是对象固有的还是在比较数值参数时也应该使用“是”?谢谢@你绝对不应该用“是”来比较数字!“is”的要点是检查两个名称是否引用同一个对象。实际上,这是一个指针比较。这使得它很快,但不适用于数字和字符串,它们(在Python中)可以有多个具有相同值的副本(即不同的对象实例)。它强调了问题不在于函数作为默认值,而在于函数的b未定义。这里b是一个全局变量。。。在我的例子中,它不好,那么它就不起作用了<当计算
g(b)
时,code>b需要在编译时存在!对不起,这不是一个好的解决方案。也许用户希望的c值为零?然后c将被函数g(b)设置为其他值,即使这不是用户的意图,那么你就有麻烦了:你应该重新考虑你的设计或者阅读一本好的Python书籍。我将给你一个例子。假设b是一个大数字,g(b)计算其因子。进一步假设,为了方便起见,我们不将数字本身和1计算为因子,因此质数的因子分解计算结果实际上为无。c是一个可选参数,用户可以指定他是否已经知道因子分解。那么,为什么要调用可能非常昂贵的g(b)?@ooboo:如果你阅读了我的答案,上面已经解释过,在你的方法中,
g(b)
总是在编译时进行计算。总是。看一下我的示例,然后尝试在
def g
内部打印(a)。即使没有调用
test
函数,它也会打印出来。你完全正确,因为没有一个示例,我把它弄得一团糟。最初我只是想让c成为列表b中某个特定元素的索引。如果用户知道它,则无需计算。
None
是Python对象
None
不是字符串
'None'
。您询问是否未填写c(意思是
None
)以使其成为
g(b)
。给出的答案完全正确。因为用户指定
None
的唯一方法是不提供第三个参数,这是您的问题。您的意思是什么?我不能把一个也不传作为论点?缺少对象并不等同于将其设置为“无”。例如:type()给出了一个错误,但是type(None)='NoneType'silenghost修复了它,多亏了他。对不起,我赶去吃午饭,结果很难看,而且有错误。但这是一个有效的解决方案,如果我真的想将“sentinel”作为参数c传递,Paolo Bergantino的解决方案就会崩溃,“sentinel”现在是命名空间中的额外变量。@Maiku Mon:sentinel的关键在于它不是c的正常值,它是一个特殊值,意味着“请为我计算c=g(b);你不想把它作为c的正常值来传递。@John,这个问题可以这样解决。OP已预先计算了
c
。因此,如果他将它传递给
f
,他就不希望再次计算它。如果他不及格,那就需要计算。@John,我理解它是如何工作的。我的论点的第一部分可能毫无意义,因为很可能没有人会使用“哨兵”作为参数,但我仍然不喜欢它。这只是我的偏见。
def f():
  sentinel = object()
  def tmp(a, b, c=sentinel):
    if c is sentinel:
      c = g(b)
  return tmp
f = 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)