如果我将城市列表作为变量传递,则任务按预期完成。
def count_top_rt(tweet_set):
for tweet in tweet_set:
print(tweet)
tweet_set = ["Sydney", "London", "Paris"]
print(tweet_set)
如果我在函数定义中错误输入了参数名称,那么任务仍然完成,因为 tweet_set 变量是全局的。
def count_top_rt(mis_typed_arguament):
for tweet in tweet_set:
print(tweet)
tweet_set = ["Sydney", "London", "Paris"]
print(tweet_set)
感觉好像没有正确地传递论证是错误的。我有两个问题:
答案 0 :(得分:3)
参数是否正确通过'?
是的,参数在第一个示例中正确传递:您的例程仅取决于输入参数。
有什么方法
在模块化哲学中,无法有效地防止此问题:您的功能不允许 了解任何外部信息。这就是"纯粹"模块化编程和Python的功能有点不一致。
作为程序员,确保这一点的方法是使用不太可能发生碰撞的变量名称。在这种情况下,请将测试驱动程序(您的主程序)中的 tweet_set 的名称更改为其他名称。如果这是一个常设测试用例,请使用不太可能出现在函数中的名称,例如 TEST_DRIVER_tweet_set 。
编程实践
您可以使用编辑器中的搜索功能突出显示每个名称的所有匹配项。如果依次突出显示每个参数和变量名称,并且"找到所有",您可以看到哪些没有正确输入。
高级技术 ......只是让你知道"某一天" ...
有一些Python功能允许函数查看堆栈,获取下一个函数的堆栈帧(调用此函数的堆栈帧),并检查其活动变量。如果您确实需要这样做,您可以让您的函数根据每个堆栈框架中的变量名称检查自己的参数名称,一直到操作系统中的主程序。
很少有这种情况有用。
答案 1 :(得分:2)
有一种简单的方法可以检查:
>>> def count_top_rt(tweet_set):
... print(id(tweet_set))
... for tweet in tweet_set:
... print(tweet)
>>> tweet_set = ["Sydney", "London", "Paris"]
>>> count_top_rt(tweet_set)
1951490534472
Sydney
London
Paris
>>> id(tweet_set)
1951490534472
>>> tweet_set2 = ["Sydney", "London", "Paris"]
>>> count_top_rt(tweet_set2)
1951490565832
Sydney
London
Paris
>>> id(tweet_set2)
1951490565832
如您所见,当变量作为变量传递时,无论全局的名称是什么,局部变量都会变为reference
。那是因为解释器首先进入locals堆栈来检查变量(它是一个引用的原因是因为函数'参数'行为),然后才引用全局变量。
答案 2 :(得分:1)
防止这种情况的最佳方法是避免全局变量。将所有代码放入函数和类中。
def count_top_rt(tweet_set):
for tweet in tweet_set:
print(tweet)
def main():
tweet_set = ["Sydney", "London", "Paris"]
count_top_rt(tweet_set)
main()
如果您在NameError
的定义中拼错参数名称,则会抛出count_top_rt
。