表达式logic=_changelog_txt
:
def writeChangelog(repo, milestone, overwrite=False, extension=u'.txt',
logic=_changelog_txt): # HERE
"""Write 'Changelog - <milestone>.txt'"""
outFile = _outFile(dir_=CHANGELOGS_DIR,
name=u'Changelog - ' + milestone.title + extension)
if os.path.isfile(outFile) and not overwrite: return outFile
issues = getClosedIssues(repo, milestone, skip_labels=SKIP_LABELS)
return logic(issues, milestone, outFile)
def writeChangelogBBcode(repo, milestone, overwrite=False):
"""Write 'Changelog - <milestone>.bbcode.txt'"""
return writeChangelog(repo, milestone, overwrite, extension=u'.bbcode.txt',
logic=_changelog_bbcode) # no errors here
def _changelog_txt(issues, milestone, outFile):
with open(outFile, 'w') as out:
out.write(h2(_title(milestone)))
out.write('\n'.join(ul(issues, closedIssue)))
out.write('\n')
return outFile
给了我 Unresolved reference \_changelog\_txt
。什么是做我想要的最pythonic方式?另见:What is the best way to pass a method (with parameters) to another method in python
答案 0 :(得分:2)
这是一个有序的问题。由于在定义函数`writeChangelog时尚未定义_changelog_txt
,因此会抛出错误。
这有效:
def b(s):
print s
def a(f=b):
f("hello")
a()
这不是:
def a(f=b):
f("hello")
def b(s):
print s
a()
应该注意,这与关键字参数默认值是函数无关。在定义函数之前,它可能是任何其他未定义的对象。当解释器遇到_changelog_txt
时,没有def writeChangelog
这样的东西。
在这种情况下,重新排序代码是一个不错的选择。
运行时期间的情况不同,因为在运行任何解释器之前已经遇到所有def
s。这就是为什么人们很少遇到python的这类问题。
答案 1 :(得分:0)
作为DrV答案的补充:
在Python中,当解释器第一次看到而不是在调用时,会评估函数的签名。因此,就范围而言,您的代码等同于以下内容:
b = a
a = 1
输出:
b = a
NameError: name 'a' is not defined
我希望你明白,为什么你的代码不起作用。
旁注:虽然这种行为使得默认参数表达式的评估范围更加明显,但它也是一个容易出错的来源,例如:
def foo(bar = []):
bar.append(1)
return bar
print(foo())
print(foo())
输出:
[1]
[1, 1]
此处,默认值始终是相同的列表 - 在foo
的所有调用中 - 因为函数签名仅在一次时进行评估。解决方案是使用None
作为默认值并进行显式检查:
def foo(bar = None):
if bar is None:
bar = []
bar.append(1)
return bar
print(foo())
print(foo())
输出:
[1]
[1]