【问题标题】:Python default arguments and argument namesPython 默认参数和参数名称
【发布时间】:2012-01-21 05:55:42
【问题描述】:

我想知道“a=a”和“b=b”是否会导致问题/意外行为?代码在示例中运行良好。

def add_func(a=2,b=3):
   return a+b

a=4
b=5
answer = add_func(a=a, b=b)

谢谢

【问题讨论】:

    标签: python


    【解决方案1】:

    据我所知,虽然我很想被证明是错误的。

    正式语言参考定义the lexical structure of a function call。重要的是它将“keyword_item”定义为identifier "=" expression。此外,这里是关于如何解释调用参数的说明:

    如果存在关键字参数,它们首先被转换为 位置参数,如下所示。首先,未填充的插槽列表是 为形参创建。如果有 N 个位置 参数,它们被放置在前 N 个插槽中。接下来,对于每个 关键字参数,标识符用于确定 对应的槽(如果标识符与第一个正式的相同 参数名称,使用第一个插槽,依此类推)。如果插槽是 已经填充,引发 TypeError 异常。否则,值 的参数被放置在插槽中,填充它(即使 表达式为无,它填充插槽)。当所有的论点都已 处理后,仍然未填充的插槽将填充 函数定义中对应的默认值。

    这列出了一些可能的情况。

    在简单的情况下,就像您提到的那样,有两个形式参数(ab),如果您使用 add_func(a=a, b=b) 等关键字参数指定函数调用,会发生以下情况:

    1. 创建了两个槽来保存参数。
    2. 由于您没有在调用中提供任何位置参数(只是关键字参数),因此最初没有填充任何插槽。
    3. 您的每个关键字参数都被单独分析,并且您的参数的标识符a= 部分中的“a”)与函数的所有形式参数名称(定义函数时为参数指定的名称,在我们的例子中为ab)。
    4. 发生匹配时,关键字参数的(在本例中为4!)用于填充相应的槽。
    5. 重复此操作,直到分析完所有关键字参数。如果所有插槽都没有被填满,那么 Python 会尝试为剩余的插槽分配一个默认值(如果存在)。如果不是,则会引发错误。

    因此,Python 对关键字参数中的“标识符”的处理方式完全不同。不过,这仅适用于关键字参数;显然,如果您尝试类似add_func(b, a) 的方法,即使您的参数本身被称为ba,这将不会映射到函数中的形参;你的参数会倒退。但是,add_func(b=b, a=a) 工作正常;只要它们是关键字参数,位置就无关紧要。

    【讨论】:

    • 感谢您的详细回答。我已经养成使用 'a=a' 的习惯,这样我就可以为各种事物保留相同的描述性名称 - 很高兴知道我不必重新查看所有代码并进行更改!
    【解决方案2】:

    这取决于指向的全局对象是可变的还是不可变的。不可变对象(例如整数)在修改时是副本,因此很安全。诸如列表之类的可变对象被就地修改,并且以这种方式使用是不安全的。对它们的任何更改都会在调用之间持续存在,并且可能(并且可能会)导致意外行为。

    这个:

    a=[]
    def f(a=a):
        pass
    

    等同于:

    def f(a=[]):
        pass
    

    这是 Python 程序中已知的不良做法。

    【讨论】:

    • 我认为这里的重要说明(这与在 函数调用中使用 a=a 没有真正关系)是 default parameters are evaluated once, when the function is defined
    • 感谢您指出这一点 - 我敢肯定这已经烧毁了很多人。
    • @user986065:是的,在这种情况下,通常建议使用占位符值(通常为None)作为默认值,然后在函数体中检查它(例如@ 987654326@).
    • 这完全忽略了问题的重点,即调用一个函数,而不是定义它。
    • @EthanFurman 你错了。告诉我它在哪里说它只是关于调用,还考虑它有一个def(“定义”的缩写)吗?无论他是否要求,这也是有用的信息。
    猜你喜欢
    • 1970-01-01
    • 2011-11-16
    • 1970-01-01
    • 2012-03-14
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多