python的库是干嘛的,老男人开始学python之什么是模块、包、库?

在上一篇《老男人开始学python之Flask中的“Hello World”》中,虽然只按照教程写了几行短短的代码,但是对于初学者的我来说就产生了一些疑问,有一些不明白的地方?

为什么文件名是“__init__.py”?

“__name__”是什么?

from ... import ... 是什么意思?

form ... import ... 和 import ...的区别是什么?

带着问题去看了Python基础教程模块一节记录总结一下。

参考教程:

廖雪峰:模块、使用模块、安装第三方模块

链接:http://www.liaoxuefeng.com/

一、什么是模块、包、库?

| Module(模块)| Package(包)| Library(库)|

| --------------------- | :------------------ | --------------- -: |

| 一个.py文件就称之为一个模块(Module)| 只要包含__init__.py文件的文件夹就叫做包| 参考其他编程语言的说法。就是指Python中完成一定功能的代码集合,供用户使用的代码组合。在python中是包和模块的形式 | | abc.py模块名就是abc;|1.init.py文件必须存在,否则就是一个文件夹;2.init.py文件可以为空,也可以有python代码;3. 可以有多级层次结构包含多个模块或子包组成;4.init.py`文件本身就是一个模块,模块名就是包含它的文件夹的名称; |例如常说的第三方库,是否可以简单理解为包含多个Package(包)完成某功能的一个代码集合 |

1.Package 包中都可以包含什么?

F:\pythontest\test2.py # test2模块

F:\pythontest\test3 # test3文件夹中包含__init__.py文件,因此是一个包;

│ a.py # test3.a模块;

│ b.py # test3.b模块;

│ __init__.py # 也是一个模块,名称是:test3

├─b # 包含2个模块的一个【文件夹】,但是名称和test3.b名称同名了,该【文件夹】下的模块能正常使用吗?如果这里是个同名的子包呢?

│ a.py

│ b.py

├─c # 一个空【文件夹】

├─d # 因为包含__init__.py文件,因此是一个子包

│ a.py # 模块名:test3.d.a

│ b.py # 模块名:test3.d.a

│ __init__.py # 模块名:test3.d

└─e # 包含2个模块的一个【文件夹】,该文件夹下的2个模块能用吗?

a.py # 暂认为模块名为:test3.e.a

b.py # 暂认为模块名为:test3.e.b

如上所示,一个包中可以包含:模块(a、b)、包含模块的文件夹(b、e)、空文件夹(c)、子包(d)。

【说明】到了这里解决了第1个问题,为什么文件名是“__init__.py”,因为它是一个Package(包);

下边做一些测试:

#F:\pythontest\test3\a.py代码如下:

def a():

return "my name is 'a'"

#F:\pythontest\test3\b.py代码如下:

def b():

return "my name is 'b'"

#F:\pythontest\test3\b\a.py代码如下:

def a():

return "我是B文件夹下的 'a'"

#F:\pythontest\test3\b\b.py代码如下:

def b():

return "我是B文件夹下的 'b'"

#F:\pythontest\test3\d\a.py代码如下:

def a():

return "我是D子包中的 'a'"

#F:\pythontest\test3\d\b.py代码如下:

def b():

return "我是D子包中的 'b'"

__init__.py 文件全部为空,F:\pythontest\test2.py文件中代码分别为如下几种情况的执行结果:

-----------------------------------------------------------------------------------

import test3

x = test3.a.a()

print (x)

#执行结果:

F:\pythontest>flask\Scripts\python.exe test2.py

Traceback (most recent call last):

File "test2.py", line 2, in

x = test3.a.a()

AttributeError: 'module' object has no attribute 'a'

【总结】:因为导入的模块名为test3,也就是test3文件夹下的`__init__.py `文件,而该文件为空,所以找不到test3.a模块中的a函数;

-----------------------------------------------------------------------------------

使用import test3.a 导入test3.a模块,即test3文件夹下的a.py文件,就可以正常执行:

import test3.a

x = test3.a.a()

print (x)

#执行结果:

F:\pythontest>flask\Scripts\python.exe test2.py

my name is 'a'

-----------------------------------------------------------------------------------

#代码如下:

import test3.b

x = test3.b.b()

print (x)

#执行结果:

F:\pythontest>flask\Scripts\python.exe test2.py

my name is 'b'

#代码更改如下:测试导入b文件夹中的b模块

import test3.b.b

x = test3.b.b.b()

print (x)

#执行结果:没有模块test3.b.b,test3.b不是一个包;

F:\pythontest>flask\Scripts\python.exe test2.py

Traceback (most recent call last):

File "", line 2218, in _find_and_load_unlocked

AttributeError: 'module' object has no attribute '__path__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "test2.py", line 1, in

import test3.b.b

ImportError: No module named 'test3.b.b'; 'test3.b' is not a package

-----------------------------------------------------------------------------------

如果给b文件夹下放一个空__init__.py文件,这时候b文件夹就成了test3的一个子包则:

import test3.b

x = test3.b.b()

print (x)

#执行结果:

F:\pythontest>flask\Scripts\python.exe test2.py

Traceback (most recent call last):

File "test2.py", line 2, in

x = test3.b.b()

AttributeError: 'module' object has no attribute 'b'

【总结】因为导入test3.b模块的时候实际上b子包把test3.b模块覆盖了,实际上导入的是b文件夹中的__init__.py文件,而该文件为空,因此找不到b函数;

#更改代码如下:导入test3.b模块,即test3\b\__init__.py

import test3.b

x = test3.b.a.a()

print (x)

#同时修改test3\b\__init__.py文件代码如下:

import test3.b.a

#执行结果:

F:\pythontest>flask\Scripts\python.exe test2.py

我是B文件夹下的 'a'

这个时候就是test3\b\__init__.py文件中导入了test3.b.a模块,然后在test2.py文件中导入了test3.b模块即test3\b\__init__.py文件,换句话说就是在test3\b\__init__.py文件中引入了test3\b\a.py文件,然后在test2.py文件中又引入了test3\b\__init__.py文件,因此a.py中的a函数能被正常执行。

-----------------------------------------------------------------------------------

#最后来看看e文件夹中的模块文件能否被正常导入并使用模块中的函数?

代码如下:

import test3.e.a

x = test3.e.a.a()

print (x)

#执行结果:

F:\pythontest>flask\Scripts\python.exe test2.py

我是E文件夹下的 'a'模块

从执行结果来看,是可以正常运行的。

更改一下代码:

import test3.e

x = test3.e.a.a()

print (x)

执行结果:

F:\pythontest>flask\Scripts\python.exe test2.py

Traceback (most recent call last):

File "test2.py", line 2, in

x = test3.e.a.a()

AttributeError: 'module' object has no attribute 'a'

从以上两例测试,可以看到虽然e只是个文件夹不是子包,但是该文件夹下的模块文件依然可以被导入。

上边的两个问题:

含2个模块的一个【文件夹】,但是名称和test3.b名称同名了,该【文件夹】下的模块能正常使用吗?如果这里是个同名的子包呢?

如果在test3包中,含有一个b.py和一个b文件夹,则b.py文件(模块)可以被导入,而b文件夹中的.py文件不能被导入;

如果b文件夹是一个子包,则子包覆盖b.py;

【注意】不要重名,以免混淆!

文件夹e,不是子包,该文件下包含2个.py文件(模块),该文件夹下的2个模块能用吗?

可以被导入使用。这是为什么呢?

二、如何使用Module(模块)?

import 命令为导入Module(模块)命令,而Module指的就是一个.py文件,其实就可以认为是在一个.py文件中引入另外一个.py文件。

1. 使用导入Module(模块)命令import

有几种格式:

命令

解释

import module

导入单个模块

import module as name

导入单个模块并重命名

import moudule1, moudule2,module3,...

一次导入多个模块

import moudule1 as name1,module2 as name2,...

一次导入多个模块并重命名

一般在文件首部导入所有模块,推荐顺序如下:

python标准库

第三方模块

应用程序自定义模块

2. 使用from...import...语句导入模块的属性(变量、函数、对象)

命令

解释

from module import name1,name2,name3

单行导入

from module import name1,name2,\ name3

多行导入

from module import *

导入全部属性,一般不推荐使用,适合模块中变量名很长和很多的情况。容易覆盖当前命名空间中现有的名字

当试图加载一个模块的时候,Python会在指定的路径下搜索对应的.py文件,如果找不到,就会报错。

默认情况下,Python解释器会搜索当前文件夹、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中。

有两种方法修改搜索路径:

一是直接修改sys.path,添加要搜索的文件夹:sys.path.append('路径')

第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。

模块被导入时,加载的时候模块顶层代码会被执行,一个模块无论被导入多少次,只加载一次,可以防止多次导入时代码被多次执行。

内建函数reload可以重新导入一个已经存在的模块。

三、 “__name__”是什么?

简单的说:

1.如果模块(就是一个.py)文件是直接执行的,则__name__值就等于__main__;

2.如果模块是被导入的时候,__name__的值就是模块名;

#test_name2.py 代码为:

def test_name2(): # 定义一个函数test_name2

b = __name__ # 将__name__赋值给变量b

return b # 函数返回变量b的值

if __name__ == "__main__": # 如果__name__ 等于字符串__main__ 就可以认为是直接执行的test_name2.py文件,则打印test_name2()函数的返回值;

print (test_name2())

#test_name1.py 代码为:

import test_name2 # 导入模块 test_name2

print (test_name2.test_name2()) # 打印test_name2模块中的test_name2函数值;

直接执行test_name2的结果:结果为__main__

F:\pythontest>flask\Scripts\python.exe test_name2.py

__main__

直接执行test_name1的结果:结果为模块名

F:\pythontest>flask\Scripts\python.exe test_name1.py

test_name2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值