Python中关键字参数问题及调试经验分享

python中的关键字参数

Python中关键字参数问题及调试经验分享

这是一篇简短的文章,简要描述了我前几天在尝试调试某人的代码时遇到的问题 - 答案对你来说可能是完全显而易见的,但我花了一段时间才解决,所以我想我应该记录下来这里。

这是一篇关于我前几天在尝试调试某人的代码时遇到的问题的简短文章 - 答案对你来说可能是完全显而易见的,但我花了一段时间才弄清楚,所以我想我会把它记录下来下面这里。

我被叫去帮忙解决的问题是这样的一行代码:

我请求帮助的问题是这行代码:

t.do_something(a=5, b=10)t.do_something(a=5, b=10) 

其中 t 是类的实例。现在,这不是我通常编写代码的方式——我倾向于只在使用了位置参数之后才使用关键字参数——但它提醒我,在 Python 中,以下对函数 f(a, b) 的调用是相等的:

其中 t 是类的实例。现在,这不是我通常编写代码的方式——我倾向于只在使用位置参数之后使用关键字参数——但这提醒我,在 Python 中,以下对函数 f(a, b) 的调用是等效的:

无论如何,回到原来的代码:它给出了以下错误:

无论如何,回到原来的代码:它给出了以下错误:

do_something() got multiple values for argument 'a'do_something() got multiple values for argument 'a' 

我认为这很奇怪,因为在调用该方法时,给定值肯定只有一个。

我认为这很奇怪,因为调用该方法时绝对只有一个给定的值。

如果您认为自己是一名相当高级的 Python 程序员,那么您可能想在这里停下来看看您是否可以找出问题所在。有什么想法吗?

如果您认为自己是一名相当高级的 Python 程序员,您可能想停下来看看是否能找出问题所在。有什么想法吗?

当你想了想之后,请继续下面的内容……

想了一会儿,我继续说……

我查看了 t.do_something() 的定义,它看起来像这样:

我查看了 t.do_something() 的定义,它看起来像这样:

你现在可能已经注意到问题了——虽然乍一看我看不出有什么问题……肯定只有一个名为 a 的参数,而且它绝对没有被传递两次……所以这是怎么回事?!

你现在可能已经注意到了这个问题 - 尽管乍一看我看不出有什么问题......肯定只有一个名为 a 的参数,而且它绝对不会被传递两次......那么这是怎么回事?

您现在可能已经注意到......这个方法缺少 self 参数 - 并且应该被定义为 do_something(self, a, b)。将其更改为它可以正常工作,但值得思考一下为什么我们会收到该特定错误。

您可能已经注意到......该方法缺少 self 参数 - 它应该定义为 do_something(self, a, b) 。更改它以使其正常工作,但值得思考一下为什么我们会收到该特定错误。

首先,让我们看一下当您忘记添加 self 作为实例方法的第一个参数时可能会出现的更“标准”错误。我们可以通过仅调用该方法而不使用关键字参数(即 t .do_something(1, 2))来看到这一点,它给出:

首先,让我们看看当您忘记将 self 添加为实例方法的第一个参数时可能会遇到的“标准”错误。我们可以通过调用不带关键字参数的方法 (ietdo_something(1, 2) ) 来看到这一点,它给出:

TypeError: test_noself() takes 2 positional arguments but 3 were givenTypeError: test_noself() takes 2 positional arguments but 3 were given 

现在,一旦您已经进行 Python 编程一段时间,您就会非常熟悉这个错误,因为您忘记将 self 作为实例方法的第一个参数。产生此特定错误的原因是 Python 将始终向实例方法传递 self 的值以及您为该方法提供的参数。因此,当您运行代码时:

现在,一旦您编写 Python 程序一段时间,您就会非常熟悉这个错误,因为您忘记使用 self 作为实例方法的第一个参数。出现此特定错误的原因是 Python 始终将实例方法的自身值与您提供给该方法的参数一起传递。所以当你运行代码时:

Python 将在“幕后”改变这一点,并实际运行:

Python“在幕后”更改它并实际运行:

t.do_something(t, 1, 2)t.do_something(t, 1, 2) 

由于 do_something 仅定义为接受两个参数,因此您会收到错误。当然,如果您的函数能够接受三个参数(例如,如果有可选的第三个参数),那么您会发现 t (在本例中是 self 的值)作为第一个参数传递(a)、1 作为第二个参数的值 (b) 和 2 作为第三个参数的值(可以称为 c)。这是一个很好的提醒您方法的第一个参数仅按照约定称为 self 的方法 – 并且 Python 本身并不关心您如何称呼它(尽管您应该始终将其称为 self!)

由于 do_something 仅定义为接受两个参数,因此您会收到错误。当然,如果你的函数能够接受三个参数(例如,如果有一个可选的第三个参数),那么你会发现t(本例中为self的值)作为第一个参数(a)传递, 1 为第二个自变量 (b) 的值,2 为第三个自变量(可能称为 c)的值。一个好的提醒是,方法的第一个参数按照惯例称为 self - Python 本身并不关心你如何称呼它(尽管你应该始终将其称为 self!)

由此,您应该能够弄清楚为什么在获取参数 a 的多个值时出现错误……发生的情况是 Python 将 self 传递给方法,作为第一个参数(我们称之为 a ),然后传递我们指定为关键字参数的其他两个参数。因此,调用该函数的“幕后”代码是:

由此,您应该能够理解为什么在获取参数 a 的多个值时出现错误...发生的情况是 Python 将 self 作为第一个参数传递给方法(我们称之为 a )然后传递我们指定为关键字参数的其他两个参数。所以调用该函数的“幕后”代码是:

但是,第一个参数称为 a,所以这基本上相当于编写:

但是,第一个参数称为 a ,因此它基本上相当于编写:

t.do_something(a=t, a=1, b=2)t.do_something(a=t, a=1, b=2) 

这显然是不明确的——因此 Python 会抛出错误。

这显然是不明确的——所以 Python 会抛出一个错误。

有趣的是,Python 抛出这个特定错误的情况是相当困难的——如果你尝试运行上面的代码,你会得到一个不同的错误:

有趣的是,Python 很难抛出这个特定的错误——如果你尝试运行上面的代码,你会得到另一个错误:

因为 Python 在尝试运行之前就已经意识到语法存在问题。您可以使用字典解包来管理它:

因为Python在尝试运行之前就知道语法存在问题。可以使用字典解压来管理:

def f(a, b):
    pass
d = {'a':1, 'b':2}
f(1, **d)def f(a, b):
    pass
d = {'a':1, 'b':2}
f(1, **d) 

这里我们定义一个带有两个参数的函数,然后用 a 的单个位置参数调用它,然后使用字典解包的 ** 方法获取字典 d 并将每个键值对转换为关键字参数,值组合。

这里我们定义一个带有两个参数的函数,然后使用 a 作为单个位置参数来调用它,然后使用 ** 字典解包来获取 d 的字典方法,并将每个键值对转换为关键字参数和值组合。

所以,如果你能比我更快地解决这个问题,那么恭喜你——但我希望它能让你更多地思考 Python 如何处理位置和关键字参数。需要记住的几点:

如果您比我更快地解决了这个问题,那么恭喜您,但我希望它能让您更多地思考 Python 如何处理位置和关键字参数。需要记住的几点:

译自:

python中的关键字参数

你可能想看:
« 上一篇
下一篇 »

相关推荐

python爬虫教程PDF,Python爬虫书PDF

2026年09月02日

31阅读

外国教程python,python编程教学视频

2026年09月02日

25阅读

python简明教程沈洁元,python详细基础教程

2026年09月02日

21阅读

python库包教程,python 包

2026年09月02日

27阅读

python教程大全集,python教程600集

2026年09月02日

26阅读

python入门教程完整版,python零基础入门全套教程视频

2026年09月02日

22阅读