Python - 将带参数作为参数的方法传递给另一个方法 - 指定默认值

时间:2014-07-01 12:37:11

标签: python python-2.7

表达式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

2 个答案:

答案 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]