当前位置: 首页 > news >正文

Python模块引用

Python模块引用有两种方法

绝对路径引入

Python 在搜索模块时,依次搜索sys.path里的位置,直到找到模块为止。

sys.path
官方文档说明:A list of strings that specifies the search path for modules. Initialized from the environment variable PYTHONPATH, plus an installation-dependent default.

sys.path 初始化的时候有两部分:os.environ[‘PYTHONPATH’] 和 默认的安装依赖的一些路径(例如 python 安装的根目录 和 pythonxx.zip),是python的搜索模块的路径集,是一个list

下面命令可以查看当前的搜索路径:

import sys
print(sys.path)
输出:

C:\Users\Administrator\Desktop\pythontest
C:\Python27\Lib\idlelib
C:\Windows\system32\python27.zip
C:\Python27\DLLs
C:\Python27\lib
C:\Python27\lib\plat-win
C:\Python27\lib\lib-tk
C:\Python27
C:\Python27\lib\site-packages

以上输出是python的sys.path的路径列表,它是一个list。默认情况下python导入文件或者模块的话,他会先在sys.path里找模块的路径。如果没有的话,程序就会报错。

PYTHONPATH
如果我们使用 PYTHONPATH 中的 modules,那么在运行 python 前,就要把 path 加到 os.environ[‘PYTHONPATH’],在运行 python 后再加,那些模块不能直接被导入

而且当前脚本的路径默认会在这个list里面,比如:C:\Users\Administrator\Desktop\pythontest。所以当前脚本import 模块(通常是脚本文件),如果是这个脚本当前目录的情况下,是不会报错的(报错信息:找不到模块)。

sys.path的初始值来源于两个。一个是系统的PYTHONPATH变量,因此可通过设置该变量,来设置 Python 默认的搜索位置。比如:

export PYTHONPATH=/opt/python:$PYTHONPATH
echo $PYTHONPATH
将该命令放在系统初始化脚本(/etc/environment)或者 BASH 初始化脚本(~/.bashrc)里,可以对每个新开的窗口有效。

sys.path的另一个来源是当前执行程序所在的目录 (而不是当前目录)。比如当前目录下文件夹./cc下有一个b.py,那么执行./cc/b.py时,./cc(而不是./!)将被加到sys.path:

python ./cc/b.py

相对路径引用

上面说的是搜索模块都是指绝对路径引用。对于非系统目录,就需要操纵sys.path。但操纵sys.path有外溢效果,因为它是一个全局变量。对于同一个库里的模块的互相引用,可以考虑使用相对路径:

from . import abc
from .abc import fool
from …up import foo
但相对路径有两个很恶心的问题,使得用法极为受限。其中一个是:

Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always main, modules intended for use as the main module of a Python application should always use absolute imports.

包含相对路径 import 的 python 脚本不能直接运行,只能作为 module 被引用。原因正如手册中描述的,所谓相对路径其实就是相对于当前 module 的路径,但如果直接执行脚本,这个 module 的 name 就是__main__, 而不是 module 原来的 name , 这样相对路径也就不是原来的相对路径了,导入就会失败。

在使用相对引用的文件中,不能有 main 方法,只执行作为一个 module 进行引用,而不是直接执行脚本。

举个简单例子。假设./cc/目录下已有一个./cc/b.py(内容为空)。当前目录下的./a.py内容为:

from .cc import b
那么直接运行python ./a.py将会报错:

ModuleNotFoundError: No module named ‘main.cc’; ‘main’ is not a package
另一个是常见的错误是: ValueError: attempted relative import beyond top-level package。

注意不光是无法直接执行,imp.load_source以及用importlib.util实现的类似功能,都无法导入这样的文件模块。因此相对引入在实际应用中使用极为受限。

相关文章:

  • 鸿蒙OSUniApp 实现一个精致的日历组件#三方框架 #Uniapp
  • NSSCTF [HNCTF 2022 WEEK4]
  • CS4334立体声D/A转换器:为高品质音频设计提供低成本的解决方案
  • Vue 和 React 状态管理的性能优化策略对比
  • C#高级编程:IO和序列化
  • 【SSL部署与优化​】​​HTTP/2与HTTPS的协同效应
  • OkHttp连接池
  • Spring集成Redis中禁用主机名DNS检测
  • springboot AOP 接口限流(基于IP的接口限流和黑白名单)
  • 在Oracle到GreatSQL迁移中排序规则改变引发的乱码问题分析及解决
  • MySQL--day1--数据库概述
  • 洞若观火 - 服务网格的可观测性魔法 (Istio 实例)
  • 基于 Spring Boot 瑞吉外卖系统开发(十五)
  • STC32G12K12实战:串口通信
  • Vector和list
  • STMCubeMX使用TB6612驱动编码轮并进行测速
  • 102. 二叉树的层序遍历递归法:深度优先搜索的巧妙应用
  • 业务中台-典型技术栈选型(微服务、容器编排、分布式数据库、消息队列、服务监控、低代码等)
  • vue3基础学习 [简单标签] (vscode)
  • 基于 Spring Boot 瑞吉外卖系统开发(十四)
  • 娃哈哈:自4月起已终止与今麦郎的委托代工关系,未来将坚持自有生产模式
  • 中国结算澄清“严查场外配资”传闻:账户核查为多年惯例,无特殊安排
  • 新闻1+1丨城市,如何对青年更友好?
  • 联合国第二届运动会闭幕,刘国梁受邀成为“联合国运动会大使”
  • 彭丽媛同巴西总统夫人罗桑热拉参观中国国家大剧院
  • 美国拟向阿联酋和沙特AI公司出口数十万枚芯片