【问题标题】:Python - Passing Arguments CleanlyPython - 干净地传递参数
【发布时间】:2017-04-05 08:50:21
【问题描述】:

如果我将城市列表作为变量传递,则任务按预期完成。

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)

感觉没有正确传递参数是错误的。我有两个问题:

  • 在第一个版本中,参数是否“正确”传递?
  • 有哪些方法可以确保正确传递参数?

【问题讨论】:

  • 永远不要对全局变量使用与局部变量相同的名称。那么这个问题永远不会发生。
  • 如果您使用 PyCharm 或类似的 IDE,它会在您自动执行此操作时告诉您。
  • @kindall 第二个函数的问题不是他对全局和局部使用了相同的名称,而是for 循环没有使用它应该使用的局部变量。
  • 你为什么在乎?您甚至不调用该函数。无论如何你最好不要使用全局变量。

标签: python python-2.7 arguments parameter-passing


【解决方案1】:

参数是否“正确”传递?

是的,在第一个示例中参数传递正确:您的例程仅依赖于输入参数。

有哪些途径

在模块化理念中,您无法有效地防止此问题:您的函数不允许了解任何外部信息。这就是“纯”模块化编程和 Python 的特性有点不一致的地方。

作为程序员,确保这一点的方法是使用不太可能发生冲突的变量名。在这种情况下,请将测试驱动程序(您的主程序)中的 tweet_set 名称更改为其他名称。如果这是一个常规测试用例,请使用不太可能出现在函数中的名称,例如 TEST_DRIVER_tweet_set

编程实践

您可以使用编辑器中的搜索功能突出显示每个名称的所有出现。如果您依次突出显示每个参数和变量名称并“查找所有”,您可以看到哪些输入不正确。

先进的技术 ...只是让你知道“有一天”...

有一些 Python 功能可以让函数查看堆栈,获取下一个函数(调用此函数的函数)的堆栈帧,并检查其活动变量。如果你真的真的需要这样做,你可以让你的函数根据每个堆栈帧中的变量名检查它自己的参数名,一直到操作系统中的主程序。

很少有这种情况有用。

【讨论】:

    【解决方案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。那是因为解释器首先去局部堆栈检查变量(它是一个引用的原因是因为函数的参数的行为),然后才引用全局。

    【讨论】:

      【解决方案3】:

      防止这种情况的最佳方法是避免使用全局变量。将所有代码放入函数和类中。

      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()
      

      如果您在count_top_rt 的定义中拼错了参数名称,这将引发NameError

      【讨论】:

        猜你喜欢
        • 2021-12-31
        • 2021-10-23
        • 1970-01-01
        • 2012-08-18
        • 2014-08-27
        • 1970-01-01
        • 2012-06-01
        • 1970-01-01
        • 2015-05-28
        相关资源
        最近更新 更多