当我在函数中传递一个完全不同的参数名称时会发生什么?

时间:2012-02-19 21:27:35

标签: python

假设我有这个功能:

def print_a_line(line_count, f):
    print line_count, f.readline()

我叫它:

current_line = 3
print_a_line(current_line, current_file)

现在发生了什么? line_count = 3还是line_count = current_line = 3?

另外,如果我传递不同的参数名称是不好的(就像我在这里用current_line而不是line_count做的那样?)

3 个答案:

答案 0 :(得分:4)

  

现在发生了什么? line_count = 3还是line_count = current_line = 3?

line_countprint_a_line的调用中绑定到3。变量current_line不受调用的影响。

  

另外,如果我传递不同的参数名称是不好的(就像我在这里用current_line而不是line_count做的那样?)

这根本不是坏事。您正在使用位置参数而不是命名参数。

在Python中,有两种参数:位置参数和命名参数。声明为上面的print_a_line函数的函数仅使用位置参数。仅具有命名参数的函数可能类似于

def print_a_line_2(line_count=3, f=None):
    if f is not None:
        print line_count, f.readline()

具有位置和命名参数的函数可能看起来像

def print_a_line_2(line_count, f, append_newline=True):
    if append_newline:
        print line_count, f.readline()
    else:
        print line_count, f.readline(),

位置参数被称为位置的原因是只有你传递的参数的位置才重要。因此,您可以将您喜欢的任何两个表达式写为print_a_line的参数,并且首先传递的参数将绑定到line_count,并且传递给第二个的参数将绑定到f在执行print_a_line期间。

命名参数并非如此,但语法不同。要传递命名参数,请编写name=expression而不是简单地编写expression。所以,要打电话给print_a_line_2,你可以写

print_a_line_2(line_count=3, f=current_file)

并且参数的名称来自等于等号之前的,而不是等号之后的名称。

有关命名和位置参数的更多信息,我建议您查看the Python tutorial

编辑:无论何时拨打line_count(current_line, current_file)

,都会发生什么?

Python解释器维护有关程序的若干信息,它维护的一些重要事项是符号表,它将名称(变量)绑定到它们的值,以及当前语句指针。每当当前语句指针到达行

print_a_line(current_line, current_file)

Python解释器在符号表中查找print_a_linecurrent_linecurrent_file。它发现print_a_line绑定到您在问题中定义的函数,current_line绑定到3,current_file绑定到文件对象(这是一个很大的实现 - 定义的数据结构,为了便于表示,我将调用F,大写的F区别于小写f,我们将稍微相遇)。由于print_a_line是一个函数,解释器使用参数3和F调用函数。为此,它保存当前的执行状态,将变量line_count绑定到3,将f绑定到F在符号表中,并将当前语句指针移动到print_a_line函数的第一行,即

print line_count, f.readline()

然后执行内置print语句的方式与执行原始函数调用的方式非常相似,查找符号表中的所有变量,并在函数中调用f.readline()与调用print_a_line的整体函数相同。然后,当print_a_line函数返回时,Python解释器从符号表中删除line_countf,并将语句指针移回到之前保存的位置。然后在调用print_a_line之后继续执行代码行。

答案 1 :(得分:3)

你混淆了范围。我们假设您的文件如下所示:

def print_a_line(line_count, f):
    print line_count, f.readline()

def main():
    current_line = 3
    print_a_line(current_line, current_file)

if __name__ == "__main__":
    current_file = open('file.txt')
    main()

main中,您有current_line=3current_line是本地变量。方法print_a_line和变量current_file是全局的,这就是main可以使用它们的原因。在print_a_line中,您有局部变量line_countf,它们分别与current_linecurrent_file相同。但是,由于current_linemain的本地line_countprint_a_linecurrent_line == line_count的本地,因此True无法评估{{1}}的范围。

这样做绝对不是一件坏事 - 相同的值可能意味着不同范围内的不同事物,变量的名称应反映这一点。

答案 2 :(得分:1)

在其他人推荐的地方阅读。在定义和调用函数时使用不同的名称并不是一件坏事;事实上,我会推荐它,直到你掌握了范围和所有这些。