python - 在Python2.7中如何使用主脚本和其他用户定义函数中的变量

标签 python python-2.7 function variables global-variables

问题的一些背景知识。我正在用 Python2.7 编写代码,运行良好。但出于可用性和维护目的,我决定将其分成模块,这对我来说是新的,因此遇到了一些问题。虽然我已经能够通过点击和试用方法使其发挥作用,但不确定这是否是正确的方法,因此在这里分享。这里共享的代码是驱动相同逻辑、顺序和方法的真实代码的简化复制。

MainEx.py是最高层运行的脚本

from LogIn_1 import LogIn
global NumTry
NumTry = 2
LogIn()
# xx is here just to show NumTry variable is further used in MainEx script
xx = NumTry*3

基本上,我在这里试图传达的是 NumTry 变量在 MainEx.py (最高级别的脚本)以及 LogIn() 函数中使用。并且也将被我正在创建的其他函数使用。

LogIn_1.py是用户定义的函数

def LogIn():
   from MainEx import NumTry
   # following are some computations involving NumTry
   print NumTry

运行 MainEx.py 给出结果:

2
2

问题: 1. 不知道为什么它会生成两次结果 2. 这看起来很奇怪,MainEx 导入 LogIn_1,LogIn_1 导入 MainEx。类似于相互导入变量的乒乓球情况。

我能够通过以下更改获得正确的结果: MainEx.py

from LogIn_1 import LogIn
global NumTry
NumTry = 2
#LogIn()
# xx is here just to show NumTry variable is further used in MainEx script
xx = NumTry*3

LogIn_1.py

def LogIn():
   from MainEx import NumTry
   # following are some computations involving NumTry
   print NumTry
LogIn()

运行 MainEx.py 给出结果:

2

我正在尝试了解避免 future 出现问题的最佳实践。

最佳答案

如果您在代码中添加一堆打印语句,您可以遵循详细信息:

# MainEx.py
print 'MainEx: start'
from LogIn_1 import LogIn
print 'MainEx: after Login import'
global NumTry
NumTry = 2
print 'MainEx: before Login() call'
LogIn()
print 'MainEx: after Login() call'
xx = NumTry*3
print 'MainEx: finish'

# LogIn_1.py
print 'start LogIn_1'
def LogIn():
    print '  Login(): start'
    from MainEx import NumTry
    print '  Login(): after MainEx import'
    print NumTry
    print '  Login(): finish'
print 'finish LogIn_1'

输出:

MainEx: start
start LogIn_1
finish LogIn_1
MainEx: after Login import
MainEx: before Login() call
  Login(): start
MainEx: start                        # Code in MainEx running again!
MainEx: after Login import
MainEx: before Login() call
  Login(): start
  Login(): after MainEx import
2
  Login(): finish
MainEx: after Login() call
MainEx: finish
  Login(): after MainEx import
2
  Login(): finish
MainEx: after Login() call
MainEx: finish

如您所见,将 (a) 循环导入与 (b) 具有顶级副作用的代码相结合会导致相反的结果。特别是,当 from MainEx import NumTryLogin() 调用中运行时,Python 似乎必须重新执行 MainEx 中的代码,因为该模块还没有 NumTry 属性,导致重复打印。我并没有真正期待这个结果......但它就是这样。

最佳实践建议:

  • 将导入语句放在模块的顶部,而不是放在函数或类内。

  • 设计您的代码以避免循环导入。您的程序模块最终具有某种层次结构:您的低级模块不会从您自己的代码库中导入任何内容;并且您的较高级别模块导入您的较低级别模块。

  • 设计您的模块,确保其顶层不会发生。模块应该只定义类、定义函数、分配常量或导入较低级别的模块。只有系统的主模块应该执行某些操作 - 并且该操作应该是调用您的顶级函数(传递任何命令行参数),甚至该调用也应该是有条件的,如下所示:

    import sys
    
    def main(args):
        ...
    
    def foo():
        ...
    
    def bar():
        ...
    
    if __name__ == '__main__':
        main(sys.argv[1:])
    

关于python - 在Python2.7中如何使用主脚本和其他用户定义函数中的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41627681/

相关文章:

r - 使用 For 循环和 If Else 创建函数

python - Discord.py purge 命令中的人员列表和已删除消息数

python - 什么是识别 gmail 中的 "original message"前缀的好正则表达式?

python - 用于 Python 的 Vim 自动完成功能

python - 代理无法通过 SSL 连接工作

jQuery 插件 : Adding Callback functionality

python - openpyxl (2.4.8) 风格背景问题;总是黑色

python - 在Python中读取文件时如何自动处理解压?

python - 在 Robot Framework 中用 Python 登录日志

javascript - 带函数的 JavaScript 闭包是如何工作的?