导入模块中全局变量的可见性

2023-12-02

我在 Python 脚本中导入模块时遇到了一些困难。我将尽力描述该错误,为什么会遇到它,以及为什么我要使用这种特定的方法来解决我的问题(我将在稍后描述):

假设我有一个模块,在其中定义了一些实用函数/类,它们引用在将导入该辅助模块的命名空间中定义的实体(让“a”成为这样的实体):

module1:

def f():
    print a

然后我有主程序,其中定义了“a”,我想将这些实用程序导入其中:

import module1
a=3
module1.f()

执行程序会触发以下错误:

Traceback (most recent call last):
  File "Z:\Python\main.py", line 10, in <module>
    module1.f()
  File "Z:\Python\module1.py", line 3, in f
    print a
NameError: global name 'a' is not defined

类似的问题也被问过过去(两天前,呃)已经提出了几种解决方案,但我并不认为这些解决方案符合我的要求。这是我的具体背景:

我正在尝试制作一个连接到 MySQL 数据库服务器并使用 GUI 显示/修改数据的 Python 程序。为了简洁起见,我在一个单独的文件中定义了一堆与 MySQL 相关的辅助/实用函数。然而它们都有一个共同的变量,这是我最初定义的inside实用程序模块,这是cursor来自 MySQLdb 模块的对象。 我后来意识到cursor对象(用于与数据库服务器通信)应该在主模块中定义,这样主模块和导入到其中的任何内容都可以访问该对象。

最终结果将是这样的:

实用程序_模块.py:

def utility_1(args):
    code which references a variable named "cur"
def utility_n(args):
    etcetera

我的主要模块:

程序.py:

import MySQLdb, Tkinter
db=MySQLdb.connect(#blahblah) ; cur=db.cursor()  #cur is defined!
from utilities_module import *

然后,一旦我尝试调用任何实用程序函数,它就会触发上述“全局名称未定义”错误。

一个特别的建议是在实用程序文件中包含“from program import cur”语句,如下所示:

实用程序_模块.py:

from program import cur
#rest of function definitions

程序.py:

import Tkinter, MySQLdb
db=MySQLdb.connect(#blahblah) ; cur=db.cursor()  #cur is defined!
from utilities_module import *

但这是循环导入或类似的东西,最重要的是,它也会崩溃。所以我的问题是:

我到底如何才能使主模块中定义的“cur”对象对导入其中的辅助函数可见?

感谢您抽出时间,如果解决方案已发布在其他地方,我深表歉意。我自己找不到答案,我的书中也没有更多的技巧。


Python 中的全局变量是全局的到一个模块,不跨所有模块。 (很多人对此感到困惑,因为在 C 语言中,全局变量在所有实现文件中都是相同的,除非你明确地使它static.)

有不同的方法可以解决这个问题,具体取决于您的实际用例。


在走这条路之前,问问自己这是否真的需要全球化。也许你真的想要一堂课,f作为实例方法,而不仅仅是一个自由函数?然后你可以做这样的事情:

import module1
thingy1 = module1.Thingy(a=3)
thingy1.f()

如果你确实想要一个全局的,但它只是供人使用module1,将其设置在该模块中。

import module1
module1.a=3
module1.f()

另一方面,如果a被很多模块共享,把它放在其他地方,然后让每个人导入它:

import shared_stuff
import module1
shared_stuff.a = 3
module1.f()

…并且,在 module1.py 中:

import shared_stuff
def f():
    print shared_stuff.a

Don't use a fromimport 除非该变量旨在成为常量。from shared_stuff import a将创建一个新的a变量初始化为任意值shared_stuff.a导入时提到的,这个新的a变量不会受到赋值的影响shared_stuff.a.


或者,在极少数情况下,您确实需要它真正全局化,就像内置模块一样,将其添加到内置模块中。 Python 2.x 和 3.x 之间的具体细节有所不同。在 3.x 中,它的工作方式如下:

import builtins
import module1
builtins.a = 3
module1.f()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

导入模块中全局变量的可见性 的相关文章

随机推荐

  • 如何修复:异步方法的返回类型必须为 void、Task 或 Task [AppName]

    我正在使用 VS Code 并遵循 ASP NET Core EF Core 教程 并承认我不太清楚 async await 和 Task 是如何工作的 嗯 我知道前两个 但不知道第三个 我第一次实现一个存储库 以及与之配套的 Unitof
  • IP地址? - 可可

    我如何制作一个 GUI 程序 只需单击一个按钮即可显示您的 IP 地址 拜托 没有什么困难的解释 我不久前刚刚开始使用 Cocoa Thanks Kevin 您可以通过两种方式获取IP地址 1 如果您想获取当前使用网络上的本地ip地址 可以
  • 为什么顶层显示 2 个窗口?

    我正在尝试制作一个 tkinter 应用程序 当第一个窗口 根 关闭时 它不会关闭所有内容 其他窗口 我尝试过使用Toplevel 它非常适合其他程序中的弹出窗口 但不适用于制作基础级别 from tkinter import top To
  • 尝试使用模板创建类的新实例,出现意外错误

    试图做一个B inary S earch Tree 简称BST 使用模板 当我尝试创建 BST 的新实例时 出现意外错误 我希望解决方案不涉及指针 因为我想将它们保持在最低限度 现在我有 template
  • Spring Boot StackOverFlowError:空

    当我想通过 foreach 循环保存存储库时遇到问题 通过 Foreach 循环用户来并将其保存到另一个实体 用户类 公开课出勤率 Id GeneratedValue strategy GenerationType AUTO private
  • 如何为svg提供响应式设计?

    我是拉斐尔的新手 我在div里面写了svg标签 请参阅此示例http jsfiddle net dhana36 bvs6P 1 使用 CTRL 和 CTRL 你会发现区别 HTML div class outer div
  • 递归思维的算法是什么? (就具体例子而言)

    我就是无法理解递归 我理解所有概念 将解决方案分解为更小的案例 并且在一遍又一遍地阅读它们后我可以理解解决方案 但我始终无法弄清楚如何使用递归来解决问题 有没有系统的方法来提出递归解决方案 有人可以向我解释一下他们尝试解决以下递归问题时的思
  • Android - 动态添加视图到视图中

    我有一个视图布局
  • INNO设置:如何获取主显示器的分辨率?

    我正在尝试使用 INNO 编写安装程序脚本 但我陷入了困境 我需要获取运行安装程序的计算机的屏幕分辨率 并使用该值在桌面上创建一个以该分辨率为一的快捷方式的论点 我知道如何创建快捷方式 但是我不知道如何提取屏幕分辨率以及如何传递该信息 可能
  • 在 CUDA 中,什么是内存合并,它是如何实现的?

    CUDA 全局内存事务中的 合并 是什么 即使读完我的 CUDA 指南后我还是无法理解 怎么做 在CUDA编程指南矩阵示例中 逐行访问矩阵称为 合并 或者逐列访问矩阵称为合并 哪一个是正确的 为什么 此信息可能仅适用于计算能力 1 x 或
  • 启用 COM 接口封送处理需要什么?

    我有一个没有类型库的 32 位 ATL COM 组件 它为一个给定的类提供了一个类工厂 该类实现了多个接口 当我将它用作进程内服务器时 一切正常 客户端调用 CoCreateInstance 实例化对象 并且 QueryInterface
  • 使用实体框架导航属性而不创建大量查询(避免 N+1)

    我一直在使用 Entity Framework Profiler 来测试 MVC 项目中的数据访问 并且遇到了几个页面 其中由于 N 1 问题 我进行的数据库查询远多于我需要的数量 这是一个简单的例子来说明我的问题 var club thi
  • 将字符串拆分为 | Java 中的(管道)[重复]

    这个问题在这里已经有答案了 我有以下文字 ARIYALUR ARIYALUR CHENNAI CHENNAI COIMBATORE COIMBATORE CUDDALORE CUDDALORE DINDIGUL DINDIGUL ERODE
  • 在 Yii 框架中设置会话

    我正在用 Yii 开发一个网站 我的页面中有一个按钮 我需要在用户单击它时设置一个会话变量 并在用户单击另一个按钮时获取会话值 我怎样才能做到这一点 Use CWebUser状态方法 set session variable Yii app
  • 对 stackexchange api 的 Http 请求返回不可读的 json

    我正在尝试从 stackexchange api 获取一些 json 数据 接收 OAuth 代码和访问令牌工作正常 但是当调用实际的数据获取端点时 响应看起来确实很奇怪 可能是编码或类似的 该请求如下所示 var client reque
  • 如果网络中断,socket 会发生什么情况

    假设一个简单的网络模型 A 已成功创建到 B 的 TCP 连接 并且它们正在这样相互通信 A lt gt B 我知道如果A上的程序死掉 例如核心转储 这将导致向B发送RST数据包 因此B的任何读取尝试都会导致EOF 而B的任何写入尝试都会导
  • 从城市名称获取纬度和经度

    在我当前的 Android 应用程序中 我想根据输入的城市名称 街道名称或邮政编码获取坐标 我怎样才能做到这一点 此致 通过网络获取地理坐标 private static JSONObject getLocationInfo String
  • 如何根据另一个向量中的条件从向量中删除元素?

    我有两个等长的向量 我想根据其中一个向量中的条件从中删除元素 应对两者应用相同的删除操作 以便索引匹配 我想出了一个解决方案std erase 但速度非常慢 vector
  • 带问号的 nvarchar 列结果

    我正在尝试更新队列项目并检索其列文本内容 问题是诸如希伯来字符之类的特殊符号会导致问号 通过直接制作 我可以完美地看到文本SELECT条款 在sql management studio Message s column hey 当我尝试检索
  • 导入模块中全局变量的可见性

    我在 Python 脚本中导入模块时遇到了一些困难 我将尽力描述该错误 为什么会遇到它 以及为什么我要使用这种特定的方法来解决我的问题 我将在稍后描述 假设我有一个模块 在其中定义了一些实用函数 类 它们引用在将导入该辅助模块的命名空间中定