【问题标题】:Python: good way to pass variable to multiple function callsPython:将变量传递给多个函数调用的好方法
【发布时间】:2016-10-13 14:21:31
【问题描述】:

在接下来的情况下需要帮助。我想通过在具有命令执行名称和经过时间的函数中打印小的完成报告来在我的脚本中实现调试模式,例如:

def cmd_exec(cmd):
    if isDebug:
        commandStart = datetime.datetime.now()
        print commandStart
        print cmd
    ...
    ... exucuting commands
    ...
    if isDebug:
        print datetime.datetime.now() - command_start
    return

def main():
    ...
    if args.debug:
        isDebug = True
    ...
    cmd_exec(cmd1)
    ...
    cmd_exec(cmd2)
    ...

如何将 isDebug 变量简单地传递给函数? 我应该使用“全局 isDebug”吗?

因为

    ...
    cmd_exec(cmd1, isDebug)
    ...
    cmd_exec(cmd2, isDebug)
    ...

看起来很糟糕。请帮我找到更优雅的方式。

【问题讨论】:

    标签: python function arguments global-variables


    【解决方案1】:

    isDebug 是应用于函数cmd_exec 的状态。对我来说,这听起来像是一个类的用例。

    class CommandExecutor(object):
    
        def __init__(self, debug):
            self.debug = debug
    
        def execute(self, cmd):
            if self.debug:
                commandStart = datetime.datetime.now()
                print commandStart
                print cmd
            ...
            ... executing commands
            ...
            if self.debug:
                print datetime.datetime.now() - command_start
    
    def main(args):
        ce = CommandExecutor(args.debug)
        ce.execute(cmd1)
        ce.execute(cmd2)
    

    【讨论】:

    • 感谢您的回复。你能再解释一件事吗?如果 cmd_exec 函数不仅从 main 调用,而且还从许多其他函数调用怎么办?这是否意味着我将不得不使用一个类实例而不是一个变量来操作
    【解决方案2】:

    Python 有一个内置的 __debug__ 变量可能很有用。

    if __debug__:
        print 'information...'
    

    当您以python test.py 运行程序时,__debug__True。如果您以python -O test.py 运行它,它将是False

    我在我的项目中执行的另一个选项是在导入后在文件开头设置一个全局 DEBUG var:

    DEBUG = True
    

    然后您可以在函数范围内引用这个DEBUG var。

    【讨论】:

      【解决方案3】:

      您可以使用模块来创建共享的变量。这比全局更好,因为它只影响专门寻找变量的代码,它不会污染全局命名空间。它还允许您在不需要主模块了解的情况下定义某些内容。

      这是因为模块是 Python 中的共享对象。每个import 都会返回对同一个对象的引用,并且对该模块内容的修改会立即共享,就像全局一样。

      my_debug.py:

      isDebug = false
      

      main.py:

      import my_debug
      
      def cmd_exec(cmd):
          if my_debug.isDebug:
              # ...
      
      def main():
          # ...
          if args.debug:
              my_debug.isDebug = True
      

      【讨论】:

      • 感谢您的解决方案。问题是我经常切换模式。并且只在脚本开头添加'-d'选项来切换调试模式更方便
      • @VadimK 我不确定反对意见是什么。我在这里展示的代码位是直接从您的问题中复制而来的。
      • 是的,我的意思是要打开/关闭调试模式,我每次都需要编辑 my_debug.py 文件
      • @VadimK 不,这根本不是真的 - 看看我的例子!
      • @VadimK 感谢您的接受。我意识到我没有彻底解释我的答案,所以我添加了一点。
      【解决方案4】:

      为此,我会使用部分/currying,基本上是预先填充一个变量。

      import sys
      from functools import partial
      import datetime
      
      def _cmd_exec(cmd, isDebug=False):
          if isDebug:
              command_start = datetime.datetime.now()
              print command_start
              print cmd
      
          else:
              print 'isDebug is false' + cmd
      
          if isDebug:
              print datetime.datetime.now() - command_start
          return
      
      #default, keeping it as is...
      cmd_exec = _cmd_exec
      
      #switch to debug
      def debug_on():
          global cmd_exec
      
          #pre-apply the isDebug optional param
          cmd_exec = partial(_cmd_exec, isDebug=True)
      
      
      def main():
          if "-d" in sys.argv:
              debug_on()
      
          cmd_exec("cmd1")
          cmd_exec("cmd2")
      
      main()
      

      在这种情况下,我在命令行上检查 -d 以打开调试模式,并通过使用 isDebug = True 创建一个新函数在函数调用上预填充 isDebug。

      我认为即使是其他模块也会看到这个修改后的 cmd_exec,因为我在模块级别替换了该函数。

      输出:

      jluc@explore$ py test_so64.py
      isDebug is falsecmd1 isDebug is falsecmd2

      jluc@explore$ py test_so64.py -d
      2016-10-13 17:00:33.523016 cmd1 0:00:00.000682 2016-10-13 17:00:33.523715 cmd2 0:00:00.000009

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-23
        • 1970-01-01
        • 2012-11-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多