20

我已经开始学习python,我想问你一些我认为这门语言有一点魔力的东西。

我想指出,在学习 python 之前,我使用过 PHP,但我没有注意到这一点。

发生了什么 - 我注意到 Python 中的一些调用构造函数或方法采用这种形式。

object.call(variable1 = value1, variable2 = value2)

例如,在烧瓶中:

app.run(debug=True, threaded=True)

这个约定有什么理由吗?或者语言基础是否存在一些语义上的原因?我在 PHP 中没有像在 Python 中那样经常看到类似的东西,因为我真的很惊讶。我真的很好奇是否有一些魔法或者它只是更容易阅读代码的约定。

4

5 回答 5

27

这些称为关键字参数,它们通常用于使调用更具可读性。

它们还可以用于以与声明参数不同的顺序传递参数,或者跳过一些默认参数但将参数传递给其他参数,或者因为函数需要关键字参数……但可读性是它们存在的核心原因。

考虑一下:

app.run(True, False)

你知道这两个论点是什么意思吗?即使你能猜到只有两个合理的参数是线程和调试标志,你怎么能猜出哪个是第一个呢?你能做到的唯一方法是找出类型app是什么,并检查app.run方法的文档字符串或定义。

但在这儿:

app.run(debug=True, threaded=False)

很明显这意味着什么。


值得一读的常见问题解答参数和参数有什么区别?,以及上述链接附近的其他教程部分。然后,您可以阅读函数定义的参考以获取有关参数的完整详细信息,并阅读有关参数的完整详细信息的调用,最后是inspect有关各种参数的模块文档。

这篇博客文章试图总结这些参考资料中的所有内容,这样您就不必阅读整个混乱的方式。最后的例子也应该用来说明为什么混淆参数和参数,关键字参数和默认参数,参数解包和可变参数等会导致你误入歧途。

于 2013-08-12T19:47:30.653 回答
4

通过关键字指定参数通常比仅按位置指定参数产生的错误风险更小。考虑这个函数来计算贷款支付:

def pmt(principal, interest, term):
    return **something**;

当一个人试图计算他们购买房屋的摊销时,可能会这样调用它:

payment = pmt(100000, 4.2, 360)

但是很难看出哪些值应该与哪个参数相关联。如果不检查文档,我们可能会认为它应该是:

payment = pmt(360, 4.2, 100000)

使用关键字参数,调用变得自记录:

payment = pmt(principal=100000, interest=4.2, term=360)

此外,关键字参数允许您在调用站点更改参数的顺序,并且一切仍然正常:

# Equivalent to previous example
payment = pmt(term=360, interest=4.2, principal=100000)

有关详细信息,请参阅http://docs.python.org/2/tutorial/controlflow.html#keyword-arguments

于 2013-08-12T19:51:42.957 回答
0

它们是通过关键字传递的参数。关键字参数和位置参数在语义上没有区别。

它们通常像“选项”一样使用,并为这种情况提供了更具可读性的语法。想想这个:

>>> sorted([2,-1,3], key=lambda x: x**2, reverse=True)
[3, 2, -1]

与(python2):

>>> sorted([2,-1,3], None, lambda x: x**2, True)
[3, 2, -1]

在第二个示例中,您能说出Noneor的含义True吗?

请注意,python3 中引入了仅关键字参数,即只能使用此语法指定的参数。在 python2 中,任何参数都可以通过位置指定(使用时除外,**kwargs但这是另一个问题)。

于 2013-08-12T19:50:05.650 回答
-1

没有“魔法”。

一个函数可以采用:

  • 位置参数(args)
  • 关键字参数(kwargs)

一直都是这个顺序

尝试这个:

def foo(*args, **kwargs):
    print args
    print kwargs

foo(1,2,3,4,a=8,b=12)

输出:

(1, 2, 3, 4)
{'a': 8, 'b': 12}

Python 将位置参数存储在一个必须是不可变的元组中,并将关键字存储在字典中。

于 2013-08-12T19:49:54.827 回答
-2

该约定的主要用途是它允许在两者之间可能存在一些默认值时设置某些输入。当一个函数有很多参数时它特别有用,其中大多数参数都可以正常工作,但需要将一些参数设置为其他值才能使函数按需要工作。

例子:

def foo(i1, i2=1, i3=3, i4=5):
   # does something


foo(1,2,3,4)

foo(1,2,i4=3)

foo(1,i2=3)

foo(0,i3=1,i2=3,i4=5)
于 2013-08-12T19:47:54.753 回答