python3 包

执行文件为test.py,内容

#test.py

import aaa

同级目录下创建目录aaa,然后自建空__init__.py(或者干脆建包)

需求:验证导入包就是在导入包下的__init__.py

先执行看结果

再在__init__.py添加打印信息后,重新执行

需求:

aaa.x

aaa.y

解决:在__init__.py中定义名字x和y

在aaa下建立m1.py和m2.py

#m1.py

def f1():

    print('from 1')

#m2.py

def f2():

    print('from 2')

需求:

aaa.m1 #进而aaa.m1.func1()

aaa.m2 #进而aaa.m2.func2()

解决:在__init__.py中定义名字m1和m2,先定义一个普通变量,再引出如何导入模块名

在aaa下新建包bbb

需求:

aaa.bbb

解决在aaa的__init__.py内导入名字bbb

在bbb下建立模块m3.py

#m3.py

def f3():

print('from 3')

需求:

aaa.bbb.m3 #进而aaa.bbb.m3.f3()

解决:是bbb下的名字m3,因而要在bbb的__init__.py文件中导入名字m3

绝对导入变成相对导入

需求:

aaa.m1()

aaa.m2()

aaa.m3()

解决:在aaa的__init__.py中拿到名字m1、m2、m3

包内模块直接的相对导入,强调包的本质:包内的模块是用来被导入的,而不是被执行的

用户无法区分模块是文件还是一个包,我们定义包是为了方便开发者维护

将包整理当做一个模块,移动到别的目录下,操作sys.path

包是一种通过使用‘.模块名’来组织python模块名称空间的方式。

1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)

3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件

强调:

  1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

  2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块

包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间

glance/                   #Top-level package

├── __init__.py      #Initialize the glance package

├── api                  #Subpackage for api

│   ├── __init__.py

│   ├── policy.py

│   └── versions.py

├── cmd                #Subpackage for cmd

│   ├── __init__.py

│   └── manage.py

└── db                  #Subpackage for db

├── __init__.py

└── models.py

#文件内容

#policy.py

def get():

    print('from policy.py')

 #versions.py

def create_resource(conf):

    print('from version.py: ',conf)

#manage.py

def main():

    print('from manage.py')

#models.py

def register_models(engine):

    print('from models.py: ',engine)  

注意事项

1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。

2.对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。

3.对比import item 和from item import name的应用场景:

如果我们想直接使用name那必须使用后者。

import

我们在与包glance同级别的文件中测试

1 import glance.db.models

2 glance.db.models.register_models('mysql')

rom ... import ...

需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法

我们在与包glance同级别的文件中测试

1 from glance.db import models

2 models.register_models('mysql')

3

4 from glance.db.models import register_models

5 register_models('mysql')

__init__.py文件

不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),这个文件可以为空,但是也可以存放一些初始化包的代码。

from glance.api import *

在讲模块时,我们已经讨论过了从一个模块内导入所有*,此处我们研究从一个包导入所有*。

此处是想从包api中导入所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,我们可以在这个文件中定义__all___:

#在__init__.py中定义

x=10

def func():

    print('from api.__init.py')

__all__=['x','func','policy']

此时我们在于glance同级的文件中执行from glance.api import *就导入__all__中的内容(versions仍然不能导入)。

对导入和相对导入

我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:

绝对导入:以glance作为起始

相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)

例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

在glance/api/version.py

绝对导入

from glance.cmd import manage

manage.main()

相对导入

from ..cmd import manage

manage.main()

测试结果:注意一定要在于glance同级的文件中测试

from glance.api import versions

注意:在使用pycharm时,有的情况会为你多做一些事情,这是软件相关的东西,会影响你对模块导入的理解,因而在测试时,一定要回到命令行去执行,模拟我们生产环境,你总不能拿着pycharm去上线代码吧!!!

特别需要注意的是:可以用import导入内置或者第三方模块(已经在sys.path中),但是要绝对避免使用import来导入自定义包的子模块(没有在sys.path中),应该使用from... import ...的绝对或者相对导入,且包的相对导入只能用from的形式。

比如我们想在glance/api/versions.py中导入glance/api/policy.py,有的同学一抽这俩模块是在同一个目录下,十分开心的就去做了,它直接这么做

比如我们想在glance/api/versions.py中导入glance/api/policy.py,有的同学一抽这俩模块是在同一个目录下,十分开心的就去做了,它直接这么做

1 #在version.py中

2

3 import policy

4 policy.get()

没错,我们单独运行version.py是一点问题没有的,运行version.py的路径搜索就是从当前路径开始的,于是在导入policy时能在当前目录下找到但是你想啊,你子包中的模块version.py极有可能是被一个glance包同一级别的其他文件导入,比如我们在于glance同级下的一个test.py文件中导入version.py,如下

from glance.api import versions

'''

执行结果:

ImportError: No module named 'policy'

'''

'''

分析:

此时我们导入versions在versions.py中执行

import policy需要找从sys.path也就是从当前目录找policy.py,

这必然是找不到的

'''

单独导入包

单独导入包名称时不会导入包中所有包含的所有子模块,如

在与glance同级的test.py中

import glance

glance.cmd.manage.main()

'''

执行结果:

AttributeError: module 'glance' has no attribute 'cmd'

'''

复制代码

解决方法:

1 #glance/__init__.py

2 from . import cmd

3

4 #glance/cmd/__init__.py

5 from . import manage

执行:

1 #在于glance同级的test.py中

2 import glance

3 glance.cmd.manage.main()

千万别问:__all__不能解决吗,__all__是用于控制from...import *

python3 包的更多相关文章

  1. 解决 同时安装 python3,python2环境时,用pip安装 python3 包

    应用场景 默认mac上已经安装了 python2; 而我又安装了 python3,并使用 python3; 安装了 pip 默认,pip安装的包安装在了 python2上了: 但是我想用 pip把安装 ...

  2. python3 包的发布

    发布流程大概如下 1. 首先需要有一个python包,就是一个文件夹,但是此文件夹下面有__init__.py文件,里面内容是 现在要发布包TestMsg,这就是一个python包.在同级目录下新建s ...

  3. python3包、模块、类、方法的认识

    包>>模块>>类>> 函数 包:就是一个目录,import time from+import导入包中的部分模块 直接到类 from budaoguan.common ...

  4. Python3练习题系列(10)——项目骨架构建

    目标: 如何创建<项目“骨架”目录> 包含:项目文件布局.自动化测试代码,模组,以及安装脚本. 由于编写一个Python文件可以作为一个模块,一个带__init__.py的目录算一个包. ...

  5. Windows7中如何让python2和python3共存并使用pip

    1.下载安装python2和python3 分别下载python2.7.exe.python3.6.exe并安装到C盘.E盘(如图)     2.配置环境变量 打开“系统变量”中的path文本框(如图 ...

  6. python安装tesseract

    一.最近在学习python爬虫的时候需要用到tesseract,但书上的给的教程对我并不适用,坑了好久天,才终于成功. 二.方法: 1.由于我看的是静谧博主的那本书.他给的教程在python3安装有问 ...

  7. 【Linux常见问题总结】

    1. 如何设置vim编辑器TAB的缩进量?自己在使用Linux编写Python脚本的时候发现TAB的缩进量总是太长,于是想自己修改下vim编辑器的缩进量. 在/etc/vim/ 文件夹下建立 .vim ...

  8. Python 安装 virturalenv 虚拟环境

    返回目录 本篇索引 一.概述 二.Linux下安装Python虚拟环境 三.Windows下安装Python虚拟环境 一.概述 有时候会在一台主机上安装多个不同的Python版本,用以运行不同时期开发 ...

  9. Linux桌面环境配置

    目录 更换软件源 中文输入法 firefox安装flash插件 编译安装Vim 关闭蓝牙开机自启 yakuake无法正常使用 在中文环境下将默认目录修改成英文 电脑换成了thinkpad x1c 20 ...

随机推荐

  1. centos针对postgres出现的postgresql Ident authentication failed for user

    首先:将/var/lib/..../pg_hba.conf文件中的indent全修改为trust即可. #local   all             all                    ...

  2. C# 中 finally 的用法

    当一个异常抛出时,它会改变程序的执行流程.因此不能保证一个语句结束后,它后面的语句一定会执行,在 C# 中这个问题可以用 finally 解决. 为了确保一个语句总是能执行(不管是否抛出异常),需要将 ...

  3. Extjs4 Combobox 联动始终出现loading错误的解决的方法

    当反复选者combobox 联动时,下级的Combobox 会出现loading的错误表现形式,尽管Store数据已载入完也是一样. 废话少说贴代码就知道怎样处理了:(注意红色部分的关键语句) }, ...

  4. windows 配置squid反向代理服务器

    发现Window版本的Squid 和 Linux 配置有点不一样 一.配置squid\etc目录1.squid.conf.default 拷贝一份重新命名为squid.conf2.cachemgr.c ...

  5. js 元素Dom新建并插入页面createElement

    纯js var o = document.createElement('script'); o.type = 'text/template'; o.id = 'demo'; document.docu ...

  6. PDO中捕获SQL语句中的错误

    使用默认模式-----PDO::ERRMODE_SILENT 在默认模式中设置PDOStatement对象的errorCode属性,但不进行其它不论什么操作. 比如: 通过prepare()和exec ...

  7. 经常使用socket函数具体解释

    经常使用socket函数具体解释 关于socket函数,每一个的意义和基本功能都知道,但每次使用都会去百度,參数究竟是什么,返回值代表什么意义.就是说用的少,也记得不够精确. 每次都查半天.常常烦恼于 ...

  8. mybaits返回插入成功后的自增值

    mybaits返回插入成功后的自增值 在项目中,我们经常遇到这样的情况:insert语句成功后,需要自增的id值,这个时候,我们可以通过mybatis的 useGeneratedKeys 来实现,具体 ...

  9. XtraBackup备份mysql5.1.73

    一.基础介绍 mysql5.1在源码中配备了两个版本的innodb存储引擎源码:innobase和innodb_plugin,编译安装的时候可以通过参数--with-plugins=innobase, ...

  10. 关于js语法中的一些难点(预解析,变量提前,作用域)

    ******标题很吓人************ 其实就是一个小小的例子 ,从例子中简单的分析一下作用域.预解析和变量提前的概念 <!DOCTYPE html> <html> & ...