python不接受关键字参数

python不接受关键字参数,python,keyword-argument,Python,Keyword Argument,我试图使我的代码不接受关键字参数,就像一些bulitin也不接受关键字参数一样,但是,我无法这样做。根据我有限的理解,以下是我的想法:- def somefunc(a,b): print a,b somefunc(10,20) 输出: 10 20 20 10 现在,当我运行以下命令时(我知道这不是函数定义中的关键字参数,但是,查看函数调用,它的语法似乎与调用接受关键字参数的函数时的语法相同): 输出: 10 20 20 10 我有两个问题:- 查看函数调用somefunc(

我试图使我的代码不接受关键字参数,就像一些bulitin也不接受关键字参数一样,但是,我无法这样做。根据我有限的理解,以下是我的想法:-

def somefunc(a,b):
    print a,b

somefunc(10,20)
输出:

10 20
20 10

现在,当我运行以下命令时(我知道这不是函数定义中的关键字参数,但是,查看函数调用,它的语法似乎与调用接受关键字参数的函数时的语法相同):

输出:

10 20
20 10
我有两个问题:-

  • 查看函数调用
    somefunc(b=10,a=20)
    ,而不是函数定义,这可能是对只接受普通参数的函数的调用,也可能是对接受关键字参数的函数的调用。口译员如何区分两者
  • 是否可以将我们的任何函数转换为一种形式,这样它就不会像许多内置函数那样接受关键字参数
  • 我为什么要这么做?
    我只是在检查我是否能够做到这一点,这样我就不会错过深入理解python的任何机会。我不知道python是否允许这样做

    查看函数调用somefunc(b=10,a=20)而不是函数定义,这可能是对只接受普通参数的函数的调用,也可能是接受关键字参数的函数。口译员如何区分两者

    不确定这是否正是你所问的,但如果我理解正确,答案是“不是”。无论参数在函数中如何定义,都可以使用关键字调用函数。如果使用关键字语法传递任何参数(例如,
    f(a=…)
    ),Python将相应的值绑定到函数定义中具有相同名称的参数。是否定义了默认值并不重要。这两种函数定义不会创建不同的“种类”参数,只是有些参数可能有默认值,而另一些可能没有。因此,无论您使用
    def(a)
    还是
    def(a=2)
    ,您仍然可以使用
    f(a=…)
    。唯一的限制是必须首先传递/定义位置参数(例如,不能执行
    def(a=2,b)
    f(a=2,3)
    )。另见


    至于问题的第二部分,我不知道有什么方法可以阻止Python函数接受指定参数的关键字传递值。如果仅定义
    *args
    ,则它将不接受关键字参数,但位置参数不能有单独的名称。

    可以使用任意参数列表来执行此操作。看

    例如:

    def somefunc(*args):
        print args[0], args[1]
    
    无关键字调用:

    somefunc(10,20)
    
    somefunc(a=10,b=20)
    
    给出:

    10 20
    
    使用关键字调用:

    somefunc(10,20)
    
    somefunc(a=10,b=20)
    
    给出一个错误:

    TypeError: someFunc() got an unexpected keyword argument 'a'
    

    不清楚您为什么要这样做。

    在Python中,关键字参数和位置参数之间没有太大的区别。事实上,这很简单:

    位置参数按其在函数调用中列出的顺序进行分析 关键字参数可以按任何顺序添加,但不能位于位置参数之前

    所以,如果你有这个:

    def foo(x):
        pass
    
    def foo(x,y='hello'):
        pass
    
    foo(1) # this works fine
    foo() # this is invalid, as an argument without a default isn't passed
    foo(y='hello',1) # error - positional arguments come before keyword arguments
    
    你可以做:

    foo(1) # positional
    foo(x=1) # keyword
    
    但是您不能执行
    foo()
    ,因为您没有提供默认值

    同样,如果您有:

    def foo(x):
        pass
    
    def foo(x,y='hello'):
        pass
    
    foo(1) # this works fine
    foo() # this is invalid, as an argument without a default isn't passed
    foo(y='hello',1) # error - positional arguments come before keyword arguments
    
    不要忘记阅读。

    ad 1)如果像调用
    somefunct(name=value,…)
    那样调用,Python会自动验证正确的名称。我不需要记住参数的确切标准顺序,也不需要通过每月在每次使用时查看文档来验证它是否太“神经质”,如果我记得一个函数有很好的参数描述性名称,并且将测试它们是否被Python接受。相反,所用参数的正确顺序只能通过文件进行验证。与非常长的位置参数列表相比,通过命名参数进行调用更为可取。因此,报告的行为是有根据的。(当然,简短的单字母参数“a,b”无助于防止错误。)

    ad 2)一些用C编写的具有少量固定必需参数的著名内置快速函数不支持使用命名参数调用。(例如,
    hasattr

    这是因为它们只使用简单的头
    …(…PyObject*args)
    ,因此所有命名参数都会被自动拒绝。(Python永远无法内省C源代码中参数的名称。:-)

    许多其他C函数都有一个头(…PyObject*args,PyObject*kwds),它们通过实现更复杂的验证
    PyArg\u ParseTupleAndKeywords
    并将名称写入文档字符串,明确地支持精确的名称列表


    编辑:可以在Python 3.8中通过新的函数参数语法
    /
    来指示某些函数参数必须按位置指定,不能用作关键字参数

    def somefunc(a,b,/):
    印刷品(a、b)
    
    我认为这是一个非常糟糕的Python特性,可能会导致非常不可维护和错误的代码。假设您有一个函数:

    def myurl(x, y):
        url = "{}:{}".format(x, y)
        return url
    
    尽管使用关键字参数替换位置参数看起来是个好主意,但千万不要这样做。我感到惊讶的是,没有Python选项可以阻止使用关键字参数调用此函数:

    >> print myurl(x="localhost", y=8080)
    
    如果有人发现,该库的可读性会更好,如果写为:

    def myurl(hostname, port):
        url = "{}:{}".format(hostname, port)
        return url
    
    然后,使用关键字调用作为
    myurl(x=“localhost”,y=8080)
    的其余代码将失败:

    TypeError: myurl() got an unexpected keyword argument 'x'
    

    这意味着您的局部函数变量突然变成了全局变量!我希望在Python 3中以某种方式解决这个问题。

    为什么要这样做?我只是在检查我是否可以这样做,