类从封闭scop获取kwargs

2024-05-15 22:39:10 发布

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

Python似乎在从类方法的封闭范围推断一些kwarg,我不知道为什么。我正在实施一个Trie:

class TrieNode(object):
  def __init__(self, value = None, children = {}):
    self.children = children
    self.value = value

  def __getitem__(self, key):
    if key == "":
        return self.value
    return self.children[key[0]].__getitem__(key[1:])

  def __setitem__(self, key, value):
    if key == "":
        self.value = value
        return
    if key[0] not in self.children:
        self.children[key[0]] = TrieNode()
    self.children[key[0]].__setitem__(key[1:], value)

在倒数第二行,我创建了一个新的三元曲,大概是一本空的儿童词典。但是,当我检查生成的数据结构时,树中的所有三元组都使用相同的子字典。也就是说,如果我们这样做:

>>>test = TrieNode()
>>>test["pickle"] = 5
>>>test.children.keys()
['c', 'e', 'i', 'k', 'l', 'p']

而被试的子代只能由指向新三元组的“p”组成。另一方面,如果我们进入代码的第二行到最后一行并替换为:

        self.children[key[0]] = TrieNode(children = {})

然后它就按预期工作了。不知怎的自我保护儿童dictionary作为kwarg隐式传递给TrieNode(),但为什么呢?你知道吗


Tags: 方法keytestselfreturnifvaluedef
2条回答

你有个问题。将__init__函数更改为这样

def __init__(self, value=None, children=None):
    if not children:
        children = {}

子函数的默认值只在函数创建时计算一次,而您希望它在每次调用中都是一个新的dict。你知道吗

下面是一个使用列表的简单问题示例

>>> def f(seq=[]):
...     seq.append('x') #append one 'x' to the argument
...     print(seq) # print it
>>> f() # as expected
['x']
>>> f() # but this appends 'x' to the same list
['x', 'x']
>>> f() # again it grows
['x', 'x', 'x']
>>> f()
['x', 'x', 'x', 'x']
>>> f()
['x', 'x', 'x', 'x', 'x']

正如我链接到的答案所描述的,这最终会影响到每个python程序员。你知道吗

您正在经历的行为来自以下行:

def __init__(self, value = None, children = {}):

children = {}称为mutable default argument。在这种情况下,默认参数是在函数定义上构造一次的,每次修改都会影响以后的每次函数调用(使用默认值)。 要解决此问题,应将None作为默认值传递(由于None是不可变的,因此上述行为不适用):

def __init__(self, value = None, children = None):
    self.children = children if children else {}
    self.value = value

相关问题 更多 >