加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 为什么设置一个默认参数值使这个函数成为一个闭包?

发布时间:2020-12-20 12:17:23 所属栏目:Python 来源:网络整理
导读:我正在编写一个应用程序,其中标签是可链接的,并且需要检索整个链接标签链.不允许自我引用.运行以下代码最终会得到一些非常奇怪的结果: class Tag(object): def __init__(self,name): self.name = name self.links = [] def __repr__(self): return "Tag {0}
我正在编写一个应用程序,其中标签是可链接的,并且需要检索整个链接标签链.不允许自我引用.运行以下代码最终会得到一些非常奇怪的结果:

class Tag(object):
  def __init__(self,name):
    self.name = name
    self.links = []

  def __repr__(self):
    return "<Tag {0}>".format(self.name)

  def link(self,tag):
    self.links.append(tag)


def tag_chain(tag,known=[]):
  chain = []
  if tag not in known:
    known.append(tag)
  print "Known: {0}".format(known)

  for link in tag.links:
    if link in known:
      continue
    else:
      known.append(link)
    chain.append(link)
    chain.extend(tag_chain(link,known))
  return chain

a = Tag("a")
b = Tag("b")
c = Tag("c")
a.link(b)
b.link(c)
c.link(a)

o = tag_chain(a)
print "Result:",o
print "------------------"
o = tag_chain(a)
print "Result:",o

结果:

Known: [<Tag a>]
Known: [<Tag a>,<Tag b>]
Known: [<Tag a>,<Tag b>,<Tag c>]
Result: [<Tag b>,<Tag c>]
------------------
Known: [<Tag a>,<Tag c>]
Result: []

所以,不知何故,我不小心创建了一个闭包.据我所见,已知应该已经超出范围并在函数调用完成后消失.

如果我将chain_tags()的定义更改为未设置默认值,则问题就会消失:

...
def tag_chain(tag,known):
...
o = tag_chain(a,[])
print "Result:",o
print "------------------"
o = tag_chain(a,o

为什么是这样?

解决方法

这是Python中常见的错误:

def tag_chain(tag,known=[]):
  # ...

known = []并不意味着如果已知notpplied,则将其设为空列表;事实上,它与“匿名”列表相关联.每次知道默认为该列表时,它都是相同的列表.

在这里做你想要的典型模式是:

def tag_chain(tag,known=None):
    if known is None:
        known = []
    # ...

如果未提供,则正确初始化已知的空列表.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读