假设我有这个功能:
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做的那样?)
答案 0 :(得分:4)
现在发生了什么? line_count = 3还是line_count = current_line = 3?
line_count
在print_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_line
,current_line
和current_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_count
和f
,并将语句指针移回到之前保存的位置。然后在调用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=3
,current_line
是本地变量。方法print_a_line
和变量current_file
是全局的,这就是main
可以使用它们的原因。在print_a_line
中,您有局部变量line_count
和f
,它们分别与current_line
和current_file
相同。但是,由于current_line
是main
的本地line_count
而print_a_line
是current_line == line_count
的本地,因此True
无法评估{{1}}的范围。
这样做绝对不是一件坏事 - 相同的值可能意味着不同范围内的不同事物,变量的名称应反映这一点。
答案 2 :(得分:1)
在其他人推荐的地方阅读。在定义和调用函数时使用不同的名称并不是一件坏事;事实上,我会推荐它,直到你掌握了范围和所有这些。