【问题标题】:Is it possible to use an argument's value in a default argument value assignment in Python?是否可以在 Python 的默认参数值赋值中使用参数的值?
【发布时间】:2016-08-18 03:00:03
【问题描述】:

我试图在右边的默认参数值内使用下面函数中左侧参数的值。

def function(var, vartwo = var*2):
    return vartwo


print(function(7)) #should print 14
print(function(7,6)) #should print 6

但是我得到 NameError: name 'var' is not defined。在 Python 的默认参数值中不能使用参数的值吗?你会建议我如何解决这个问题?

【问题讨论】:

  • 好吧,您需要传递实际的“默认值”,它不能是先前声明的另一个参数的名称。 def function(var, vartwo = 'blabla'): return vartwo 应该可以工作
  • 另一件事 - 如果您需要第二个参数始终作为第一个参数 - ui 认为您根本不需要第二个参数, def function(var): vartwo = var return vartwo 是同样在这里。或者如果你解释为什么你需要第二个参数这么糟糕,因为从这个上下文中不清楚
  • 我编辑了问题以更好地解释上下文。

标签: python


【解决方案1】:

这是不可能的;这个怎么样?

def function(var, vartwo = None):
    if vartwo is None:
        vartwo = var*2
    return vartwo

print(function(7))
print(function(7,6))

hack 是将默认值设置为None,然后在内部进行设置。如果不是,则返回用户输入的任何内容。

【讨论】:

  • 好吧,这解决了他当前的问题,而原来的问题仍然存在.. 不知道,没有答案 - 是否可以将先前声明的参数作为默认参数传递给下一个 - 通过 var 名称。 python 说不(正如预期的那样)。但是一般如何解决这个问题:D
  • 是的,这会起作用,但有点希望不要破解。我认为不能默认使用参数值。我将设置为答案。
  • 嗯...据我所知,var 必须被定义才能使用。
  • 不过这满足他的要求,所以+1
  • 感谢@MiroRodozov! :)
【解决方案2】:

推卸责任:

def function(var, *args):
    return (lambda var, vartwo=var * 2: vartwo)(var, *args)


print(function(7))  # should print 14
print(function(7, 6))  # should print 6

我知道 lambda 函数,但介意添加解释吗?

由于我们不能在vartwo 的定义中使用var,我们通过lambda 设置一个新的参数列表来延迟,其中var 现在已定义,vartwo 的默认值是合法的。

我通过重用var 变量名称来表示两个不同的变量(function 的形式参数和lambda 的形式参数)并充当位置占位符,使这有些混乱。

我可以而且可能应该更简单地写成:

def function(var, *args):
    return (lambda vartwo=var * 2: vartwo)(*args)

但我想保留原始问题的味道。

【讨论】:

  • 不错,非常pythonic
  • 我知道 lambda 函数,但介意添加解释吗?
  • @JoelAntonioDelacruzParedes,我添加了一些解释和简化。如果不够,请告诉我。
  • 这个解决方案是否比 vartwo = None hack 更快?
  • @JoelAntonioDelacruzParedes,这似乎是一个寻找速度的奇怪地方,但我会说“不”,我的速度较慢,尽管它在 C 级别进行条件测试,因为它的开销额外的函数调用(lambda)占主导地位。所以预计它会快 1/2。 (每次通话我们可能只用 1/2 微秒的速度说话。)
【解决方案3】:

您的操作将不起作用,因为尚未声明 var。这是另一种方法:

def function(var, multiply=False):
    if multiply:
        return var * 2
    else:
        return var

print(function(7, True))  # 14
print(function(6))  # 6

【讨论】:

    【解决方案4】:

    不,不能使用未在函数外部定义的值作为该函数的参数值。

    作为替代方案,我迟到了,但是如果 None 是第二个参数,那么可以使用简短而简单的方法怎么样?

    def function(var, *args):
        return args[0] if args else var * 2
    
    
    print(function(7))  # prints 14
    print(function(7, 6))  # prints 6
    print(function(7, None))  # prints 'None'
    

    这里,args 是在var 之后提供的参数列表,可以是一个空列表。然后,如果列表不为空(相当于第二个参数),则返回此列表的第一个元素。如果列表为空,我们返回var * 2

    这里需要注意的是,如果提供了两个以上的参数,这将不会引发相应的错误。如果len(args) > 1(记住args 是参数第一个参数之后),您可以选择手动引发TypeError,如果这对强制执行很重要。

    【讨论】:

      【解决方案5】:

      不能在默认值中使用另一个参数的值。原因很简单:默认值只计算一次:在函数定义执行时。

      一种常用的模式是默认将第二个参数设置为一个特殊的标记值,然后测试该参数是否在函数中再次设置:

      SENTINEL = object()
      
      def function(var, vartwo=SENTINEL):
          # was vartwo set?
          if vartwo is not SENTINEL:
              return vartwo
      
          return var * 2
      

      这样,即使您传入 None 或任何其他值,该函数也会正确返回 vartwo,除非您专门传递了 SENTINEL 常量。

      【讨论】:

        猜你喜欢
        • 2017-05-11
        • 2017-07-12
        • 2023-01-11
        • 2012-08-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多