惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
C
Check Point Blog
博客园 - Franky
月光博客
月光博客
T
Tenable Blog
博客园 - 聂微东
Cyberwarzone
Cyberwarzone
The GitHub Blog
The GitHub Blog
C
CERT Recently Published Vulnerability Notes
Scott Helme
Scott Helme
IT之家
IT之家
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
CXSECURITY Database RSS Feed - CXSecurity.com
F
Full Disclosure
博客园 - 司徒正美
Project Zero
Project Zero
Y
Y Combinator Blog
A
Arctic Wolf
美团技术团队
博客园 - 叶小钗
S
Securelist
F
Fortinet All Blogs
T
Threatpost
T
Threat Research - Cisco Blogs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
酷 壳 – CoolShell
酷 壳 – CoolShell
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
Recorded Future
Recorded Future
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
Schneier on Security
Apple Machine Learning Research
Apple Machine Learning Research
L
LangChain Blog
P
Privacy International News Feed
博客园_首页
S
SegmentFault 最新的问题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC
P
Proofpoint News Feed
Cisco Talos Blog
Cisco Talos Blog
AWS News Blog
AWS News Blog
阮一峰的网络日志
阮一峰的网络日志
G
Google Developers Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
雷峰网
雷峰网
P
Proofpoint News Feed
Latest news
Latest news
G
GRAHAM CLULEY

邢平cn's blog

甲骨文密钥 ssh 连不上且忘记登录密码解决方法 让 traefik 代替你的 waf(使用 CrowdSec)+ nginx + acme.sh + mtls-auth 使用 rclone 和 alist 加密和备份你的数据到公有云 邓晓芒《黑格尔辩证法讲演录》读书笔记 如何白嫖和使用 GitHub models 的 LLM(gpt4o 和 Llama-3.1-405b) 提升部署在 cloudflare、vercel 或 netlify 的网站在中国国内的访问速度和稳定性 免费通过 NS1 利用监控宝平台实现实时基于不同运营商的故障转移 记录某一测速网站的 js 逆向的过程 列举几个免费域名和权威 dns 服务器 Hexo 博客折腾 docker 学习笔记 尝试在闲置的 surface pro 4 上运行安卓应用 国内各个 as 自治系统[转] 『现学现忘』Git基础 — 19、在Git中进行忽略文件操作 让在 vpc 中的 aws lambda 函数不通过 nat 获得访问互联网的能力 cron 笔记 curl 遇到的坑 你的常用域名被其他 vercel 账号使用的解决方法 解决升级 umamiv2.11 时出现的 P3009 错误 v2ray+ws+tls 太慢解决方法 在 python 中运行 bash 实时输出结果(windows)
在存在父子文件结构情况下使用 python import
xingpingcn · 2023-04-01 · via 邢平cn's blog

在存在父子文件结构情况下使用 python import,深刻理解 python 如何引 import 用子文件和父文件。Attempted relative import with no known parent package

python

前言

网上的资料大多数都比较乱,包括 stackoverflow 也是,也就产生了这篇笔记。

文件结构和可能存在的引用链条

现在有这样一个文件夹

root

|____ a.py # 该文件作为演示的运行入口文件

|____ b.py

|____ c.py

|____ dir1

|____d.py

|____e.py

|____dir2

|____x.py

Warning (IMPORTANT)
  • 我使用的是 python3.11,该版本中不需要 __init__.py 也能把文件夹变成一个 package
  • 如果你不能引入子文件夹,则直接在该文件夹中新建一个 __init__.py,内容为空。

可能存在的引用链条有

  • a -> d -> b(引用父文件)

# a.py

import d

# d.py

import b

  • a -> d -> x -> e(引用子文件后再引用其父文件)
  • a -> b -> c
  • a -> d -> x -> c

非运行入口文件和运行入口文件

Warning (IMPORTANT)

一定要区分哪个是运行入口文件!

python a.py 中,a.py 就是运行入口文件,其他的都不是。如果你 cd dir1 & python e.py,那么 a.py 就不是运行入口文件了,e.py 才是。一般 而言运行入口文件使用绝对引入。

绝对引入和相对引入

import a 就是绝对引入,from . import a 就是相对引入。也就是说带 . 的就是相对引入。

a -> d -> b(引用父文件)

# a.py

from dir1 import d

# d.py

from .. import b

#正确写法 import b

如果你这么写的话一定会报错的,Attempted relative import with no known parent package,不报错你也不会来看我的博客()

这里假设 a.py 是运行入口文件,正确的写法是直接 import b,这是因为 b.pya.py 同级,也就是说如果是要引入同运行入口文件同级的 .py,则直接 import 就可以。

a -> d -> x -> e(引用子文件后再引用其父文件)

这个在 d.py 中就是正常的 from .dir1 import x,但是需要注意的是,在 x.py 中需要使用 from .. import e,这和上面那个引用父文件的方法不一样,所以说一定要注意哪个才是运行入口文件!!

a -> d -> x -> c

这里也出现了 a.py 引用同级的 c.py 的情况,与 x.py 引用 e.py 不同,x.py 引用 c.py 的时候直接 import c 就可以。

a -> b -> c

最后这个也是同级,import c 就可以。

在运行入口文件中引用其父文件

不是不可以,其实没什么必要这么做,因为如果后续要继续改的话会频繁出错,例如如果存在另一个同级或非同级的文件,此文件要引用原来的运行入口文件,那么原运行入口文件所引用的文件很可能就引用失败。

所以我看有些库,例如 requests,官方的 asyncio 都是只有一个层级,大家都是非运行入口文件,互相引用的时候都是用相对引入。

如果你真的要在运行入口文件中引用其父文件,那么这样写

import sys

from os import path

sys.path(path.dirname(path.dirname(path.abspath(__file__))))

import a