记一次在 Python 中因为文件路径导致的错误

2024年7月26日服务端开发评论20,612字数 1322阅读4分24秒阅读模式

记一次在 Python 中因为文件路径导致的错误

最近在编写一个自动化应用,需要管理浏览器的状态。

通过单例模式的设计,实现了只有一个浏览器实例,这样其它模块或者函数调用这个浏览器类,用的都是同一个实例,就可以管理这个浏览器的状态了。

类似下面这样调用:

def manual_test_main():
    manual_test_special_func()
    manual_test_browser_open()

def manual_test_special_func():
    from tests.web.browser import Browser
    browser = Browser()
    browser.open_browser()

def manual_test_browser_open():
    from web.browser import Browser
    browser = Browser()
    print(browser, browser.is_browser_open())

if __name__ == "__main__":
    manual_test_main()

你能从上面看出问题吗?

编辑器没有报错,导入的都是 web 目录下的 browser.py 中的 Browser 类,因为 Browser 是单例模式,理论上来说,Browser 实例化时,应该是同一个模块才对。

但是在测试中,即使浏览器打开了,获取到的浏览器状态还是关闭的,我测试了半天,也没想清楚到底是哪里出了问题,难道是我的单例模式失效了??

直到我尝试把两个 browser 对象都打印出来,才发现了不同:

记一次在 Python 中因为文件路径导致的错误

注意看,不管是它们的 id,还是对象的路径都有区别,也就是说,它们是不同的实例对象。

那么就有两个问题:

  1. 不同的路径,为什么可以调用同一个模块
  2. 路径不同,即使相同的模块也会不同吗?

这里其实就暴露了我对 Python 知识的匮乏,根据我之后的了解,这两个问题有了答案:

1. 为什么不同的路径,可以调用同一个对象

这里涉及到 Python 模块搜索路径的问题。

sys.path 是一个包含所有模块搜索路径的列表。在 Python 启动时,它会被初始化并包含以下路径:

  1. 当前工作目录sys.path 的第一个元素是运行 Python 程序时的当前工作目录。你可以使用 os.getcwd() 查看当前工作目录。
  2. 标准库目录:Python 标准库的路径。这些路径取决于 Python 的安装位置和版本。
  3. 第三方包目录:安装的第三方包所在的目录,例如使用 pip 安装的包。
  4. PYTHONPATH 环境变量:如果设置了 PYTHONPATH 环境变量,其内容会被添加到 sys.path 中。这个环境变量可以用来添加额外的路径。
  5. .pth 文件:如果存在 .pth 文件(通常位于 site-packages 目录下),这些文件的内容也会被添加到 sys.path 中。.pth 文件用于添加额外的路径到 Python 的模块搜索路径。

因为我是从 app 目录下启动的,app 目录作为当前工作目录,已经被添加到sys.path 了,那么我省略掉 app 自然也就无所谓了。

2. 路径不同,即使相同的模块也会不同吗?

即使模块内容相同,Python 将每个模块的文件路径视为不同的模块。因此,它们会被视为不同的模块实例,每个实例在内存中有不同的 id

所以即使我使用了单例模式,事实上,它们也是不同的实例。

记一次 Python 应用开发频繁假死的问题 服务端开发

记一次 Python 应用开发频繁假死的问题

问题背景 最近在开发一款自动化的应用,其中有一个自动化任务会由下面这三个按钮控制: 逻辑也很简单,我大概画下图就是这样的: 但是,在测试时,却发现了问题: 当我点击暂停任务后,此时子线程被阻塞。如果我...
Python 中单例模式的实现与使用 服务端开发

Python 中单例模式的实现与使用

实现方法 在Python中,单例模式可以通过多种方法实现。单例模式的目标是确保一个类只有一个实例,并提供一个全局访问点。以下是几种常见的实现单例模式的方法: 方法 1: 使用模块 Python中的模块...
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定