【问题标题】:Positional argument v.s. keyword argument位置参数与关键字参数
【发布时间】:2023-03-31 06:00:02
【问题描述】:

基于this

位置参数是一个不跟等号的名称 (=) 和默认值。

关键字参数后跟一个等号和一个表达式 给出它的默认值。

def rectangleArea(width, height):
    return width * height

print rectangleArea(width=1, height=2)

问题> 我假设widthheight 都是位置参数。那为什么我们也可以用关键字参数语法来调用它呢?

【问题讨论】:

  • "为什么我们也可以用关键字实参语法来调用它?"因为这就是语言的工作方式。

标签: python


【解决方案1】:

您引用的那段文字似乎对两件完全不同的事情感到困惑:

我怀疑编写该课件的人并不完全熟悉 Python :-) 因此您提供的链接质量不是很好。


在您对函数的 调用 中,您正在使用“关键字参数”功能(其中参数被命名而不是依赖于它的位置)。没有它,值将绑定到仅基于顺序的名称。所以,在这个例子中,下面的两个调用是等价的:

def process_a_and_b(a, b):
   blah_blah_blah()

process_a_and_b(1, 2)
process_a_and_b(b=2, a=1)

进一步举例,参考下面的定义和调用:

def fn(a, b, c=1):        # a/b required, c optional.
    return a * b + c

print(fn(1, 2))            # returns 3, positional and default.
print(fn(1, 2, 3))         # returns 5, positional.
print(fn(c=5, b=2, a=2))   # returns 9, named.
print(fn(b=2, a=2))        # returns 5, named and default.
print(fn(5, c=2, b=1))     # returns 7, positional and named.
print(fn(8, b=0))          # returns 1, positional, named and default.

【讨论】:

  • 在这种情况下,named 等于 keyword
  • 你说“在调用那个函数时,你使用了“命名参数”特性。”。但是你也说过“Python 引用仅在调用函数时引用位置和关键字参数”。所以,现在,我很困惑:位置和关键字参数到底是什么时候出现的?因为,正如您所说,在函数调用中,它们成为位置或命名。提前谢谢!
  • @Milan(和 Fredrick),当 Python 使用“关键字”时,我可能不应该使用“命名”——我现在已经解决了这个问题。就它何时选择位置/关键字而言,这发生在调用中(而不是定义),并且取决于您是否使用fn(10)fn(param=10)。在定义中,= 的存在与位置/关键字方面无关。
【解决方案2】:

由于 Python 3.8 引入了仅位置参数,这篇文章需要更新。

位置参数、关键字参数、必需参数和可选参数经常被混淆。位置参数不一样必需参数,关键字参数不一样可选参数。

位置参数是可以通过它们在函数调用中的位置来调用的参数。

关键字参数是可以通过名称调用的参数。

必需参数是必须传递给函数的参数。

可选参数是不能传递给函数的参数。在 Python 中,可选参数是具有默认值的参数。

  • 可选的位置参数 (Python 3.8)

    def f(a=2, /):
        pass
    
    
    f()  # Allowed, argument is optional
    f(1)  # Allowed, it's a positional argument
    f(a=1)  # Error, positional only  argument
    
  • 所需的位置参数 (Python 3.8)

    def f(a, /):
        pass
    
    
    f()  # Error, argument required
    f(1)  # Allowed, it's a positional argument
    f(a=1)  # Error, positional only argument
    
  • 可选的关键字参数

    def f(*, a=1):
        pass
    
    
    f()  # Allowed
    f(1)  # Error, keyword only argument
    f(a=1)  # Allowed, it's a keyword argument
    
  • 需要的关键字参数

    def f(*, a)
        pass
    
    
    f()  # Error, argument required
    f(1)  # Error, keyword only arguments
    f(a=1)  # Allowed, it's a keyword argument
    
  • Positional-or-keyword 可选参数

    def f(a=1)
        pass
    
    
    f()  # Allowed, argument is optional
    f(1)  # Allowed, it's a positional argument
    f(a=1)  # Allowed, it's a keyword argument
    
    # In fact this function is the same as
    def f(/, a=1, *):
        pass
    
  • Positional-or-keyword 需要的参数

    def f(a):
        pass
    
    
    f()  # Error, argument required
    f(1)  # Allowed, it's a positional argument
    f(a=1)  # Allowed, it's a keyword argument
    
    # In fact this function is the same as
    def f(/, a, *):
        pass
    

结论,参数可以是可选的或必需的,但不能同时是两个。它也可以是位置、关键字或同时是两者

Python 3.8 引入了positional-only parameters

def f(positional_argument, /, positional_or_keyword_argument, *, keyword_argument):
    pass

【讨论】:

  • 你的意思是f(/,a,*),而不是你最后两个例子中的f(*, a, /)
  • 函数中的“/”是什么,请解释一下。
  • @Lord-shiv 它表示仅位置参数的结束,不能用作关键字参数的参数。根据stackoverflow.com/questions/24735311/…
【解决方案3】:

关键字参数只是具有默认值的位置参数。您必须指定所有没有默认值的参数。换句话说,关键字参数只是“可选”的,因为如果没有特别提供,它们将被设置为默认值。

【讨论】:

  • 好吧,这是有道理的,但你能详细说明为什么它被称为“关键字”参数吗?我知道“位置”参数意味着当你调用函数时它们的位置很重要。
【解决方案4】:

在这里定义参数和参数会有所帮助。

  1. 参数:一个命名实体指定参数的函数/方法定义。
  2. 参数:传递给函数的值。

例如,

def my_function(parameter_1, parameter_2):
    pass

my_function(argument_1, argument_2)

现在当你说位置参数时,你是在说参数,所以与函数定义无关。 widthheight 在您的示例中是位置参数关键字参数(所谓的位置或关键字参数)。

您如何调用/将值传递给函数确定它们是位置参数还是关键字参数

rectangleArea(1, 2) # positional arguments
rectangleArea(width=1, height=2) # keyword arguments

很少有人知道的是,您可以通过使用参数列表中的/ 来指定仅位置参数(来自here 的示例)。

def func(positional_only1, positional_only2, /, positional_or_keyword): ...

同样,您也可以使用* 字符来设置仅限关键字的参数。

def func(positional_or_keyword, *, keyword_only1, keyword_only2): ...

最后,我们还有 var-positional 和 var-keyword(分别称为 *args 和 **kwargs)。这意味着,您可以将任意序列的位置参数或关键字参数传递给函数。

【讨论】:

    【解决方案5】:

    可以按顺序使用值或通过命名每个值来调用位置参数。例如,以下所有三个都将以相同的方式工作:

    def rectangleArea(width, height):
        return width * height
    
    print(rectangleArea(1, 2))
    print(rectangleArea(width=1, height=2))
    print(rectangleArea(height=2, width=1))
    

    【讨论】:

    • 我不认为这是正确的。根据 Python here 的官方词汇表,位置参数是一个不是关键字参数的参数。关键字参数的定义是函数调用中前面有标识符(例如name=)的参数,或者作为前面有** 的字典中的值传递。这两个定义与您的示例相矛盾。
    【解决方案6】:

    位置参数:以正确的位置顺序传递给函数的参数。下面的程序了解函数的位置参数

    #positional arguments example
    def combine(str1, str2):
    #To join str1 and str2 with str3
        str3 = str1 + str2
        print(str3)
    
    #call combine() and pass 2 strings
    combine("Well", "come")   #positional arguments 
    

    假设,我们先通过'come',然后通过'well',那么结果将是 comewell。此外,调用函数 3 字符串成为错误。

    【讨论】:

      【解决方案7】:

      了解函数的关键字参数。

      关键字参数是通过名称标识参数的参数。

      #keyword arguments example: 
      def employee(name, Id):
          print("Employee Name: ", name)
          print("Employee Id  : ", Id)
      #call employee() and pass 2 arguments
      employee(name = "inban", Id = "pay001")
      employee(Id = "pay002", name = "karthik") #we can change the order args.
      

      【讨论】:

        【解决方案8】:

        我假设宽度和高度都是位置参数。那为什么我们也可以用关键字参数语法来调用它呢?

        为了防止您可以使用仅位置参数:

        def rectangleArea(width, height, /):
            return width * height
        
        print rectangleArea(width=1, height=2)
        

        错误信息如下:

        TypeError: rectangleArea() 得到了一些作为关键字参数传递的仅位置参数:'width, height'

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-11-18
          • 1970-01-01
          • 2017-06-29
          • 1970-01-01
          • 2022-11-03
          • 2018-12-12
          • 1970-01-01
          • 2010-11-27
          相关资源
          最近更新 更多