Python创建包,导入包(入门必读)
以下内容节选自http://c.biancheng.net/view/4669.html
详细内容请看原文
《Python包》一节中已经提到,包其实就是文件夹,更确切的说,是一个包含“__init__.py”文件的文件夹。因此,如果我们想手动创建一个包,只需进行以下 2 步操作:
- 新建一个文件夹,文件夹的名称就是新建包的包名;
- 在该文件夹中,创建一个 __init__.py 文件(前后各有 2 个下划线‘_’),该文件中可以不编写任何代码。当然,也可以编写一些 Python 初始化代码,则当有其它程序文件导入包时,会自动执行该文件中的代码(本节后续会有实例)
例如,现在我们创建一个非常简单的包,该包的名称为 my_package,可以仿照以上 2 步进行:
- 创建一个文件夹,其名称设置为 my_package;
- 在该文件夹中添加一个 __init__.py 文件,此文件中可以不编写任何代码。不过,这里向该文件编写如下代码:
''' http://c.biancheng.net/ 创建第一个 Python 包 ''' print('http://c.biancheng.net/python/')
- 可以看到,__init__.py 文件中,包含了 2 部分信息,分别是此包的说明信息和一条 print 输出语句。
由此,我们就成功创建好了一个 Python 包。
创建好包之后,我们就可以向包中添加模块(也可以添加包)。这里给 my_package 包添加 2 个模块,分别是 module1.py、module2.py,各自包含的代码分别如下所示(读者可直接复制下来):
#module1.py模块文件 def display(arc): print(arc) #module2.py 模块文件 class CLanguage: def display(self): print("http://c.biancheng.net/python/")
现在,我们就创建好了一个具有如下文件结构的包:
my_package ┠── __init__.py ┠── module1.py ┗━━ module2.py
当然,包中还有容纳其它的包,不过这里不再演示,有兴趣的读者可以自行调整包的结构。
Python包的导入
通过前面的学习我们知道,包其实本质上还是模块,因此导入模块的语法同样也适用于导入包。无论导入我们自定义的包,还是导入从他处下载的第三方包,导入方法可归结为以下 3 种:
import 包名[.模块名 [as 别名]]
from 包名 import 模块名 [as 别名]
from 包名.模块名 import 成员名 [as 别名]
用 [] 括起来的部分,是可选部分,即可以使用,也可以直接忽略。
注意,导入包的同时,会在包目录下生成一个含有 __init__.cpython-36.pyc 文件的 __pycache__ 文件夹。
1) import 包名[.模块名 [as 别名]]
以前面创建好的 my_package 包为例,导入 module1 模块并使用该模块中成员可以使用如下代码:
import my_package.module1 my_package.module1.display("http://c.biancheng.net/java/")
运行结果为:
http://c.biancheng.net/java/
可以看到,通过此语法格式导入包中的指定模块后,在使用该模块中的成员(变量、函数、类)时,需添加“包名.模块名”为前缀。当然,如果使用 as 给包名.模块名”起一个别名的话,就使用直接使用这个别名作为前缀使用该模块中的方法了,例如:
import my_package.module1 as module module.display("http://c.biancheng.net/python/")
程序执行结果为:
http://c.biancheng.net/python/
另外,当直接导入指定包时,程序会自动执行该包所对应文件夹下的 __init__.py 文件中的代码。例如:
import my_package my_package.module1.display("http://c.biancheng.net/linux_tutorial/")
直接导入包名,并不会将包中所有模块全部导入到程序中,它的作用仅仅是导入并执行包下的 __init__.py 文件,因此,运行该程序,在执行 __init__.py 文件中代码的同时,还会抛出 AttributeError 异常(访问的对象不存在):
http://c.biancheng.net/python/ Traceback (most recent call last): File "C:\Users\mengma\Desktop\demo.py", line 2, in <module> my_package.module1.display("http://c.biancheng.net/linux_tutorial/") AttributeError: module 'my_package' has no attribute 'module1'
我们知道,包的本质就是模块,导入模块时,当前程序中会包含一个和模块名同名且类型为 module 的变量,导入包也是如此:
import my_package print(my_package) print(my_package.__doc__) print(type(my_package))
运行结果为:
http://c.biancheng.net/python/ <module 'my_package' from 'C:\\Users\\mengma\\Desktop\\my_package\\__init__.py'> http://c.biancheng.net/ 创建第一个 Python 包 <class 'module'>
2) from 包名 import 模块名 [as 别名]
仍以导入 my_package 包中的 module1 模块为例,使用此语法格式的实现代码如下:
from my_package import module1 module1.display("http://c.biancheng.net/golang/")
运行结果为:
http://c.biancheng.net/python/ http://c.biancheng.net/golang/
可以看到,使用此语法格式导入包中模块后,在使用其成员时不需要带包名前缀,但需要带模块名前缀。
当然,我们也可以使用 as 为导入的指定模块定义别名,例如:
from my_package import module1 as module module.display("http://c.biancheng.net/golang/")
此程序的输出结果和上面程序完全相同。
同样,既然包也是模块,那么这种语法格式自然也支持 from 包名 import *
这种写法,它和 import 包名 的作用一样,都只是将该包的 __init__.py 文件导入并执行。
3) from 包名.模块名 import 成员名 [as 别名]
此语法格式用于向程序中导入“包.模块”中的指定成员(变量、函数或类)。通过该方式导入的变量(函数、类),在使用时可以直接使用变量名(函数名、类名)调用,例如:
from my_package.module1 import display display("http://c.biancheng.net/shell/")
运行结果为:
http://c.biancheng.net/python/ http://c.biancheng.net/shell/
当然,也可以使用 as 为导入的成员起一个别名,例如:
from my_package.module1 import display as dis dis("http://c.biancheng.net/shell/")
该程序的运行结果和上面相同。
另外,在使用此种语法格式加载指定包的指定模块时,可以使用 * 代替成员名,表示加载该模块下的所有成员。例如:
from my_package.module1 import * display("http://c.biancheng.net/python")
补充:
如果你希望 python 将一个文件夹作为 Package ,那么这个文件夹中必须包含一个名为 __init__.py 的文件,即使它是空的。
如果你需要 python 将一个文件夹作为 Package 执行,那么这个文件夹中必须包含一个名为 __main__.py 的文件。
python pkg python -m pkg
(a) 当作文件夹执行的时候,__init__.py 不会被执行。对于 __main__.py 来说,变量 __package__ 是一个空字符串。
当作模块执行的时候,会先执行 __init__.py ,再执行 __main__.py 。对于 __main__.py 来说,变量 __package__ 是 Package 的名字。另外, __init__.py 和 __main__.py 中的 __name__变量的值是不同的。
(b) 对于一个 Package 来说,既然 __init__.py 必须存在,并且当作为模块执行的时候,它会先执行,我们就应该把入口函数 main() 定义在 __init__.py 中。当我们使用模块方式 -m 执行的时候, __init__.py 定义了 main() 函数,然后在 __main__.py 中调用它,就能实现我们统一入口的目的。
更详细内容,请参考原文:https://blog.51cto.com/feishujun/5513660
参考:http://c.biancheng.net/view/4669.html
https://blog.51cto.com/feishujun/5513660
原文地址:https://www.cnblogs.com/pu369/p/17251194.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 某云Music——JS破解全过程
- 和低效 IO 说再见,回头补一波 Java 7 的 NIO.2 特性
- 框架源码调试实战之easypoi异常解决方案精讲
- MySQL8.0的错误日志
- Shiro学习笔记(一)
- Shiro学习笔记(二)
- Shiro学习笔记 三(认证授权)
- Shiro学习笔记四(Shiro集成WEB)
- Shiro学习笔记五(Shiro标签,及通配符)
- Shiro学习笔记六(自定义Reaml-使用数据库设置 user roles permissions)
- Luncene学习 第一天 《入门程序》
- Luncene学习二《搜索索引》
- JavaWeb--简单分页技术
- 使用Python制作第一个爬虫程序
- 使用BeautifulSoup 爬取一个页面上的所有的超链接