代码之家  ›  专栏  ›  技术社区  ›  Jamie Marshall

从单个导入访问python应用程序中的全局变量

  •  2
  • Jamie Marshall  · 技术社区  · 8 年前

    所以,我正在尝试使用python解释器作为服务器端python应用程序的cli。然而,在加载python模块时,我得到了一种出乎意料的行为。

    我有两个python文件和一个缓存文件:

    主.py
    配置py
    缓存.json

    因此,当导入并运行main时,main()函数导入配置,然后调用函数初始化配置。初始化配置时,根据我运行的环境,从cache.json加载一些全局变量。这是一个简单的.py的例子。

    #Main.py
    import Config
    
    def main():
        """Initialize Python Application"""
        Config.init()
    
    
    if __name__ == "__main__":
        main()
    

    #Config.py
    import os
    import json
    
    Default_MSSQLPassword = ""
    Default_MSSQLUser = ""
    Default_OdbccDriver = ""
    MDGSQLP01 = ""
    
    
    def init():
        """docstring"""
    
        with open("Cache.json", "r") as f:
            dtGlobalConstants = json.load(f)
    
        Default_MSSQLPassword = dtGlobalConstants["Default_MSSQLPassword"]
        Default_MSSQLUser = dtGlobalConstants["Default_MSSQLUser"]
        Default_OdbccDriver = dtGlobalConstants["Default_OdbccDriver"]
        MDGSQLP01 = dtGlobalConstants["MDGSQLP01"]
    

    现在理论上,如果我在python解释器中调用以下命令:

    >>>from Main import main
    >>>main()
    

    config应该由main()导入,persist,并且我应该能够打印从cache.json加载的default_odbccdriver的缓存值。但我得到的是:

    >>>Config.Default_OdbccDriver
    >>>''
    

    很明显main正在导入config.py,否则在调用property.default\u odbccdriver时会出错。然而,即使default_odbccdriver的值应该是“global”(根据python对单词的奇怪定义),它的值也应该是静态的,并持久存在于导入缓存中。

    有人知道发生了什么事或者怎么解决吗?最后,我希望main()初始化一些值并公开一些使用我的应用程序的方法,但这不是一个好的开始…

    2 回复  |  直到 8 年前
        1
  •  3
  •   Netwave    8 年前

    你应该声明你的变量为 global init 函数,否则您只需设置函数的一些局部变量来隐藏全局变量:

    def init():
        """docstring"""
        global Default_MSSQLPassword
        global Default_MSSQLUser
        global Default_OdbccDriver
        global MDGSQLP01
    
        with open("Cache.json", "r") as f:
            dtGlobalConstants = json.load(f)
    
        Default_MSSQLPassword = dtGlobalConstants["Default_MSSQLPassword"]
        Default_MSSQLUser = dtGlobalConstants["Default_MSSQLUser"]
        Default_OdbccDriver = dtGlobalConstants["Default_OdbccDriver"]
        MDGSQLP01 = dtGlobalConstants["MDGSQLP01"] 
    

    正如您在注释中所说,当导入到绑定变量的会话时 Main.Config.your_var_name 为了解决这个问题,应该在模块中将它们声明为全局:

    #Config.py
    import os
    import json
    
    global Default_MSSQLPassword
    global Default_MSSQLUser
    global Default_OdbccDriver
    global MDGSQLP01
    
    Default_MSSQLPassword = ""
    Default_MSSQLUser = ""
    Default_OdbccDriver = ""
    MDGSQLP01 = ""
    
    
    def init():
        """docstring"""
        global Default_MSSQLPassword
        global Default_MSSQLUser
        global Default_OdbccDriver
        ...
    
        2
  •  0
  •   Richard Stoeffel    8 年前

    看起来您使用的配置好像是一个类,但没有将其定义为一个类。如果需要配置对象,可以如下定义:

    #Config.py
    import os
    import json
    
    class Config:
    
        def __init__(self):
            """docstring"""
    
        dtGlobalConstants = {}
    
        with open("Cache.json", "r") as f:
            dtGlobalConstants = json.load(f)
    
        Default_MSSQLPassword = dtGlobalConstants.get("Default_MSSQLPassword", "")
        Default_MSSQLUser = dtGlobalConstants.get("Default_MSSQLUser", "")
        Default_OdbccDriver = dtGlobalConstants.get("Default_OdbccDriver", "")
        MDGSQLP01 = dtGlobalConstants.get("MDGSQLP01", "")
    

    现在,当您第一次实例化配置对象时,如 config = Config() ,和 config 对象将拥有所有这些变量。

    还要注意,如果dict.get()函数在dict中找不到变量,它会将变量设置为

    如果使用类,则可以避免使用全局变量,甚至可以通过编写 get_db_object 函数,以便您可以使用config.get_db_object()创建您的db对象