在Python 3.3之前,一个目录想被当成package被导入,必须包含__init__.py文件;而在Python 3.3及以后的版本中,__init__.py文件可以不需要,直接使用import后者from语法,就能直接导入目录,这样的目录称为namespace package。

换句话说,>=Python 3.3之后,存在两种package,一种是常规的package,即包含__init__.py的目录,一种是namespace package,即不包含__init__.py的目录。

搜寻规则

当引入namespace package之后,Python的搜寻规则总结如下(这里以绝对导入为例,如果是相对导入,sys.path换成当前目录即可):

1 如果按照sys.path的路径搜寻到一个常规的package,那么Python导入这个package,本次搜寻返回;

2 如果按照sys.path的路径搜寻到一个module文件,那么导入这个文件,本次搜寻返回;

3 如果按照sys.path的路径搜寻到一个目录,并且不包含__init__.py文件,那么就将这个目录记录下来(即namespace package),同时继续按照sys.path中下一个路径开始搜寻

4 如果经过1,2,3步骤都没有搜寻到指定的目录,那么,继续按照sys.path中的一个路径开始搜寻

当遍历完成所有的sys.path中的路径,同时也没有发现常规的package和module文件,那么,就按照namespace package的__path__属性包含的路径,再进行一次搜寻,如果找到,就导入,否则,导入失败。

换句话说,namespace package中__path__属性包含的路径,起到了类似sys.path的作用。

举例来说,加入有如下目录结构:

# 当前目录是/home/username/python
mkdir -p ns/dir1/sub
mkdir -p ns/dir2/sub

在ns/dir1/sub目录下有文件mod1.py:

# ns/dir1/sub/mod1.py
print(r'dir1\sub\mod1')

在ns/dir2/sub目录下有文件mod2.py

# ns/dir2/sub/mod2.py
print(r'dir2\sub\mod2')

为了让sys.path中包含路径/home/username/python/ns/dir1和/home/username/python/dir2,我们进行如下设置:

export PYTHONPATH=/home/username/python/ns/dir1:/home/username/python/dir2

在/home/username/python目录下进入Python交互式命令行:

>>>import sys
>>>import sys.path #可以看到上述设置的路径生效了
['', '/home/username/python/ns/dir1', '/home/chaochao/python/ns/dir2',...] >>>import sub # sub被当成是一个namespace package
<module 'sub' (namespace)> >>>sub.__path__ #__path__属性中记录了两个路径,后续的查找从这两个路径开始
_NamespacePath(['/home/chaochao/python/ns/dir1/sub', '/home/chaochao/python/ns/dir2/sub']) >>>from sub import mod1 #成功导入mod1.py
dir1\sub\mod1 >>>from sub import mod2 #成功导入mod2.py
dir2\sub\mo2

需要指出的是,对于namespace package,相对导入的语法也是可以使用的,没有任何变化;同时,常规package和namespace package也是可以相互包含的,不会有任何影响。

Python中的namespace package的更多相关文章

  1. python中的namespace

    python中的名称空间是名称(标识符)到对象的映射. 具体来说,python为模块.函数.类.对象保存一个字典(__dict__),里面就是重名称到对象的映射. 可以参看下面python程序的输出: ...

  2. [Python]Python中的包(Package)

    参考官方文档中的Module和Glosssary中的描述.Module: https://docs.python.org/3/tutorial/modules.html#packagesGlossar ...

  3. Python中包(package)的调用方式

     一.什么是Python Package 如何区分你看到的目录是一个Python Package包呢?其实很简单,你只要看这个名录下是否有“__init__.py”这个文件就好了,如果有那么就是Pyt ...

  4. python中os.path 与sys.path

    看别人写的代码,会发现两个和路径设置有关的模块 os 和sys.我对这两个模块也不是特别了解.只是记录一下自己看到的,学到的. python 中我们会使用这两个模块和文件路径, 创建文件 之类的 操作 ...

  5. ## Python中的Package和Jupyter中import包问题

    前言 关于python包的一些知识 Java中的package概念 我们知道在java中的import package概念, java中的包就是一个目录,里面包含着子目录,子目录套着子目录,当需要引入 ...

  6. Python中模块(Module)和包(Package)的区别

    本文绝大部分内容转载至:廖雪峰官方网站 1. 模块(Module) 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函 ...

  7. Python中package的导入语法

    在Python中,一个目录被称为一个package.import和from语法除了导入module文件之外,还可以导入package,语法如下: # import语法 import dir1.dir2 ...

  8. python中__init__.py的作用、module和package

    控制包的导入行为: 1.声明当前文件是一个可导入的包: 2.如果当下包下有多个.py文件使用__ all__ = [ '模块名'],也就是form XXX import YYY module和pack ...

  9. Python中的内置函数

    2.1 Built-in Functions The Python interpreter has a number of functions built into it that are alway ...

随机推荐

  1. 学习笔记 - 中国剩余定理&扩展中国剩余定理

    中国剩余定理&扩展中国剩余定理 NOIP考完回机房填坑 ◌ 中国剩余定理 处理一类相较扩展中国剩余定理更特殊的问题: 在这里要求 对于任意i,j(i≠j),gcd(mi,mj)=1 (就是互素 ...

  2. python初学者日记02(正则表达式)

    写作时间:2018/12/17 作者:永远的码农(博客园) 一.正则表达式简介: 正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或R ...

  3. WSO2 API Manager 替换mysql作为数据库,解决AuthorizationUtils Could not set authorizations for the root问题

    按照wso2官网(https://docs.wso2.com/display/ADMIN44x/Changing+to+MySQL)配置AM的数据库,想从H2换成Mysql5.7,费了将近一天的时间, ...

  4. linux系统基础之---系统基本安全(基于centos7.4 1708)

  5. Action与Func 用法

    //vs2017 + framework4.6.2 //zip    https://github.com/chxl800/ActionFuncDemo //源文件git   https://gith ...

  6. 线上服务内存OOM问题定位三板斧

    相信大家都有感触,线上服务内存OOM的问题,是最难定位的问题,不过归根结底,最常见的原因: 本身资源不够 申请的太多 资源耗尽 58到家架构部,运维部,58速运技术部联合进行了一次线上服务内存OOM问 ...

  7. 爬取豆瓣电影Top250

    1 import json import requests from requests.exceptions import RequestException import re import time ...

  8. 使用ContentType处理大量的外键关系

    问题分析 在之前的一个商城的项目中使用了mysql, 提到mysql就是外键, 多对多等等一系列的表关系 因为是一个商城的项目, 这里面有优惠券, 商品有很多的分类, 不同的商品又有不同的优惠券 其实 ...

  9. Flume:source和sink

    Flume – 初识flume.source和sink 目录基本概念常用源 Source常用sink 基本概念  什么叫flume? 分布式,可靠的大量日志收集.聚合和移动工具.  events ...

  10. python网络编程之进程

    一.什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实 ...