类构造函数和关键字参数-Python如何确定哪个是意外的?

2024-06-10 20:28:48 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我定义了以下类:

class MyClass(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

通常,可以通过以下方式之一实例化该类:

>>> MyClass(1,2)
<__main__.MyClass object at 0x8acbf8c>
>>> MyClass(1, y=2)
<__main__.MyClass object at 0x8acbeac>
>>> MyClass(x=1, y=2)
<__main__.MyClass object at 0x8acbf8c>
>>> MyClass(y=2, x=1)
<__main__.MyClass object at 0x8acbeac>

很好很漂亮。

现在,我们尝试使用一个无效的关键字参数,看看会发生什么:

>>> MyClass(x=1, j=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'j'

Python正确地引发了一个类型错误,并抱怨unexpected keyword argument 'j'

现在,我们可以尝试使用两个无效的关键字参数:

>>> MyClass(i=1,j=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'i'

注意,其中两个关键字参数是无效的,但是Python只抱怨其中的一个,在本例中是'i'

允许反转无效关键字参数的顺序:

>>> MyClass(j=2, i=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'i'

那很有趣。我更改了无效关键字参数的顺序,但是Python仍然决定抱怨'i',而不是'j'。所以Python显然不会简单地选择第一个要抱怨的无效键。

让我们再试一次:

>>> MyClass(c=2, i=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'i'
>>> MyClass(q=2, i=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'i'

按字母顺序,我在i之前尝试了一个字母,在i之后尝试了一个字母,所以Python没有按字母顺序抱怨。

这里还有一些,这次在第一个位置是i

>>> MyClass(i=1, j=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'i'
>>> MyClass(i=1, b=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'i'
>>> MyClass(i=1, a=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'a'

啊哈!我让它抱怨'a',而不是'i'

我的问题是,当向类构造函数提供无效的关键字参数时,Python如何确定要投诉哪一个?


Tags: inmostinitstdinlinemyclasscallargument
1条回答
网友
1楼 · 发布于 2024-06-10 20:28:48

关键字参数存储在字典中,并应用字典顺序(例如,基于哈希算法的任意顺序、哈希冲突和插入历史记录)。

对于第一个示例,同时具有ij键的字典会导致i首先列出:

>>> dict(j=2, i=1)
{'i': 1, 'j': 2}

注意,{...}文字dict表示法从右到左插入键,而关键字解析从左到右插入关键字(这是CPython实现细节);因此在上面的示例中使用了dict()构造函数。

当两个键散列到同一个槽时,这很重要,比如ia

>>> dict(i=1, a=2)
{'a': 2, 'i': 1}
>>> {'i': 1, 'a': 2}
{'i': 1, 'a': 2}

字典输出顺序高度依赖于特定Python实现的插入和删除历史;例如,Python 3.3引入了一个随机散列种子,以防止出现严重的denial of service vector,这意味着即使在Python进程之间,字典顺序也将完全不同。

相关问题 更多 >