python import机制-python import 机制初探

引子

考虑有如下代码结构

.

├── cat

│   ├── __init__.py

│   ├── cat.py

│   └── moo.py

└── dog

├── __init__.py

└── dog.py

2 directories, 5 files

情况1:

# ./cat/cat.py

import moo

其余文件为空。如果我们用运行命令: python cat/cat.py,则程序正常运行;如果运行命令;python -m cat.cat,则会报错;

情况2:

# ./cat/cat.py

from . import moo

则运行结果相反。

其实,我们的问题早就有人提出过了。PEP 395

The fact that most methods of invoking Python code from the command line break when that code is inside a package, and the two that do work are highly sensitive to the current working directory is all thoroughly confusing for a beginner. :如果一段代码在一个包内,那么从命令行使用这段代码是非常非常容易出错的,只有2种方法可行:

在整个包的外部,python -c "from module import code,

在整个包的外部,通过-m参数执行。

如果在包内部,即使你的代码正确,也基本会出错。

分析

情况1:

当我们运行python cat/cat.py时,这时候系统的搜素路径包括./cat/,我们可以通过在./cat/cat.py中添加import sys; print(sys.path)证实这一点。

当我们运行 python -m cat.cat时,系统的搜索路径只包括.,也就是当前文件夹,我们可以通过在当前文件夹下添加一个moo.py文件,这样python -m cat.cat就不会报错了。可见,这时的搜索空间,不包括自文件夹。

情况2:

情况2其实和情况1很不一样,情况2叫做package relative import,也就是包内间接引用。顾名思义,这种引用方法只能在包内使用。也就是说,只能通过python -m cat.cat, 或者是python -c "from cat import cat" 之类的方法来使用。以下内容源自python官方文档中的 The import statement

When a module or package is contained within another package ... using leading dots in the specified module or package after from you can specify how high to traverse up the current package hierarchy without specifying exact names.

import

python中,载入一个包有几种方式:

import语句

importlib模块提供的方法

内置方法__import__ (不提倡)

python中,有module,有package。package都是module, 但module不一定是package。module只有一种,package有2种。

代码重载:importlib.reload

使用importlib.reload会重载当前代码。

import os

import importlib

import foo

print("foo.a: {}".format(foo.a))

command = "echo a=2 >> foo.py"

print(command)

os.popen(command)

importlib.reload(foo)

print("foo.a: {}".format(foo.a))

输出:

foo.a: 2

echo a=2 >> foo.py

foo.a: 2

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值