2013-06-05 178 views
62

为什么这段代码会抛出一个SyntaxError?为什么非默认参数不能遵循默认参数?

>>> def fun1(a="who is you", b="True", x, y): 
...  print a,b,x,y 
... 
    File "<stdin>", line 1 
SyntaxError: non-default argument follows default argument 

虽然下面这段代码并没有可见的错误运行:

>>> def fun1(x, y, a="who is you", b="True"): 
...  print a,b,x,y 
... 
+0

在Python是结构如何,当你定义一个函数 '高清myfunction的(position_arguments,*论点,**关键字):'' ....' – abhishekgarg

回答

72

所有必需的参数必须放在任何默认参数之前。只是因为它们是强制性的,而默认参数不是。在语法上,如果允许混合模式,解释器将决定哪些值匹配哪些参数将是不可能。如果参数未按正确顺序给出,则会引发SyntaxError

让我们看看关键字参数,使用您的函数。

def fun1(a="who is you", b="True", x, y): 
...  print a,b,x,y 

假设其允许声明功能上面, 然后用上面的声明,我们可以做出以下(常规)位置或关键字参数调用:

func1("ok a", "ok b", 1) # Is 1 assigned to x or ? 
func1(1)     # Is 1 assigned to a or ? 
func1(1, 2)    # ? 

,你会如何建议的分配函数调用中的变量,将如何使用默认参数以及关键字参数。

>>> def fun1(x, y, a="who is you", b="True"): 
...  print a,b,x,y 
... 

参考奥赖利 - 核心的Python
凡为这个功能使用的默认参数为上述函数调用语法正确。 关键字参数调用被证明对于能够提供乱序位置参数非常有用,但是,与默认参数一起,它们也可以用于“跳过”缺少的参数。

+0

从句法上讲,如果允许混合模式,解释器不可能决定哪些值匹配哪些参数。 Ruby允许遵循默认参数的非默认参数。 如何在函数调用中建议赋值变量只需使用'func1(x = 1,y = 2)'。 – weakish

+0

嗨@weakish,感谢您的评论,Python确实有一个很好的方式来实现这一点,请去搜索*参数和** kwargs –

+0

嗨@Rahul Gautam我很困惑。我认为'** kwargs'不能让'fun fun1(a =“你是谁”,b =“True”,x,y)'或类似的作品。如果你使用'def f(** kwargs)',你需要处理正文中的默认值? – weakish

0

必需的参数(那些没有默认值),必须在一开始就允许客户端代码仅提供两个。如果可选参数是在开始,这将是混淆:

fun1("who is who", 3, "jack") 

你会在第一个例子中做什么?最后,x是“谁是谁”,y是3,a =“杰克”。

9
SyntaxError: non-default argument follows default argument 

如果你要实现这一点,默认参数将变得毫无用处,因为你将永远无法使用它们的默认值,因为非默认参数后前来

在Python 3然而,你可以做到以下几点:

def fun1(a="who is you", b="True", *, x, y): 
    pass 

这使得仅xy关键字,所以你可以这样做:

fun1(x=2, y=2) 

这工作,因为不再有任何歧义。请注意,您仍然无法执行fun1(2, 2)(这将设置默认参数)。

+0

关键字只有参数是一个Python的实用的功能3.这个补丁太糟糕了,无法将它们恢复到Python 2.6和2.7版本,只是[left to expire](http://bugs.python.org/issue1745)。 –

3

让我明确两点的位置:

  • 首先非默认参数不应该遵循默认参数,这意味着你不能定义(A = B,C)中的功能定义参数的顺序功能是:
    • 位置参数或非默认参数即(A,b,C)
    • 关键字参数或默认参数即(α= “b” 中,r = “J”)
    • 关键字定位只有参数即(*参数)
    • VAR-关键字参数即(** kwargs)

def example(a, b, c=None, r="w" , d=[], *ae, **ab):

(A,B)是位置参数

(C =无)是可选参数

(r =“w”)是关键字参数

(d = [])是列表参数

(* AE)是关键字只有

(** AB)是VAR关键字参数

  • 现在次要的东西是,如果我尝试这样: def example(a, b, c=a,d=b):
当保存默认值时,

参数未定义,Python计算 并在定义函数时保存默认值

c和d没有定义,不存在,当发生这种情况时(它只存在于函数执行时)

“a,a = b”它在参数中是不允许的。

0

它是由python参数解析器的工作机制决定的。这里没什么魔法。