第051讲: 模块:__name__='__main__',搜索路径和包 | 学习记录(小甲鱼零基础入门学习Python)

(标答出处: 鱼C论坛)
《零基础入门学习Python》

本节知识点:

(一)if __name__ == '__main__' :

避免这种情况的关键在于让Python知道该模块是作为程序运行还是导入到其他程序中,为了实现这一点,你就需要使用 __name__变量,
如果是在主程序里面使用这个 __name__变量的话,那得到的是个"__main__"
如果是在模块中调用 这个 __name__变量的话,那得到的就是这个模块的名字。

>>> __name__
'__main__'
>>>
>>> tc.__name__
'TemperatureConversion'

这样的话,你就不难理解这个 if __name__ == '__main__' 这句代码的意思了。

所以在上面的模块的测试文件中,需要这样改写:

def c2f(cel):
        fah = cel * 1.8 + 32
        return fah
def f2c(fah):
        cel = (fah - 32) / 1.8
        return cel
def test():
        print("测试,0摄氏度 = %.2f华氏度"%c2f(0))
        print("测试,0华氏度 = %.2f摄氏度"%f2c(0))
 
if __name__ == "__main__":
        test()
也就是说,只有在直接运行该模块代码时(也就是测试模块的时候),__name__ 才等于"__main__",这时才运行test(),打印测试结果,
当调用该模块时, __name__ 是等于"模块名"的,就不会打印测试结果了。

(二)搜索路径:
 Python模块的导入需要一个路径搜索的过程,也就是说,你导入一个叫做 hello 的模块,Python会在预定义好的搜索路径里面找一个叫做 
 hello.py 的模块文件,如果有,则导入模块,如果没有,则导入失败,而这个搜索路径呢,就是一个列表,一组目录,我们可以 sys 模块
 中的 path 变量把它显示出来:

>>> import sys
>>> sys.path
['D:\\ProgramFiles\\Anaconda3\\Lib\\idlelib', 
'D:\\ProgramFiles\\Anaconda3\\python35.zip', 
'D:\\ProgramFiles\\Anaconda3\\DLLs', 
'D:\\ProgramFiles\\Anaconda3\\lib', 
'D:\\ProgramFiles\\Anaconda3', 
'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages', 
'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\Sphinx-1.4.6-py3.5.egg', 
'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\win32', 
'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\win32\\lib', 
'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\Pythonwin',
'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\setuptools-27.2.0-py3.5.egg']

sys 是与系统相关的模块,Python 会从上面的路径中一个一个的去搜索有没有相关的模块。这里需要解释的是,不同的系统的 sys.path 显
示的路径是不一样的,这里最佳的存放模块的位置是 '...\\lib\\site-packages',该文件夹本来就是设置类存放模块的。

另外,按照这里逻辑来说,你只需要告诉 Python 你的模块文件在哪里找,Python在导入模块的时候就可以正确找到,例如:我们想把桌面上
的一个模块导入,我们直接导入的话,是找不到的,因为桌面的路径是不属于 sys.path 的搜索路径的,我们就可以把 桌面路径加到搜索
路径中去。

import sys
sys.path.append("C:\\Users\\XiangyangDai\\Desktop")

(三)包(package):
Python中也出现了包的概念,什么是包呢,其实就像我们刚才做的,把模块分门别类的放到不同的文件夹,然后把各个文件夹的位置告诉
Python。但是包的做法更加简洁,创建一个包也非常简单,步骤如下:

在这里插入代码片

在第2步中,必须在包目录下创建一个__init__.py的模块,你可以是一个空文件,但是必须要有这个文件,因为这是Python的规定,用来告
诉Python,把这个文件夹(这个目录)当做一个包来管理。

接下来,要导入包的模块,怎么导?其实也很简单,就是使用 包名.模块名 来导入就可以了

import sys
sys.path.append("C:\\Users\\XiangyangDai\\Desktop")
import M1.TemperatureConversion as tc
 
print("32摄氏度 = %.2f华氏度"%tc.c2f(32))
print("99华氏度 = %.2f摄氏度"%tc.f2c(99))
 
>>> 
=============== RESTART: C:\Users\XiangyangDai\Desktop\calc.py ===============
32摄氏度 = 89.60华氏度
99华氏度 = 37.22摄氏度

测试题(笔试,不能上机哦~):
在这里插入图片描述
答:所有模块都有一个 name 属性,name 的值取决于如何应用模块,在作为独立程序运行的时候,name 属性的值是 ‘main’,而作为模块导入的时候,这个值就是该模块的名字了。
在这里插入图片描述
答:模块在作为独立程序运行的时候,name 属性的值是 ‘main
在这里插入图片描述
答:导入 sys 模块 使用 sys.path 查询,最后输出的是路径的列表。
在这里插入图片描述
答:可以创建一个包(package),放在 site-packages 文件夹,因为它就是用来存放你的模块文件的。
在这里插入图片描述
答:是一个包,Python 把同类的模块放在一个文件夹中统一管理,这个文件夹称之为一个包。

urllib 是 Python 负责管理 URL 的包,用于访问网址(后边我们会讲到)。
在这里插入图片描述
答:看文件夹中是否有 init.py 文件。

必须在包文件夹中创建一个 init.py 的模块文件,内容可以为空。可以是一个空文件,也可以写一些初始化代码。这个是 Python 的规定,用来告诉 Python 将该目录当成一个包来处理。

动动手:
在这里插入图片描述
在这里插入图片描述
答:因为在执行 b.py 的加载过程中,需要创建新的模块对象 b,然后执行 b.py 对应的字节码。当遇到第一条语句(import a)的时候,Python 会转而去导入 a.py 并生成模块对象 a。同样遇到第一条语句(import b)的时候,Python 就跑去导入模块 b,此时发现 b 模块已经导入(在 sys.modules 中存在),继而执行 b 模块的字节码,当执行到 a.x() 的时候,由于模块 a 此时并未完全导入,所以抛出 AttributeError 异常。

怕有些鱼油可能看不懂,小甲鱼给大家整理下,看 Python 是如何被当成猴子耍的:

执行 b.py -> import a -> 查找 a 模块 -> 未发现 a 模块对象 -> 导入 a.py -> import b -> 查找 b 模块 -> 发现 b 模块对象 -> 接着往下执行字节码(import a 已执行过,Python 有机制确保不重复导入,因而不会再执行) -> a.x() -> 在 a 模块中找不到 x(),因为 a 还没有被完全导入嘛……

好了,解决的方案也很简单,用这节课的知识,就是使用 if name == “main” 来确保 Python 不要在导入的过程中调用不该调用的函数。

# a.py
import b
 
def x():
    print('x')
 
if __name__ == "__main__":
    b.y()
 
# b.py
import a
 
def y():
    print('y')
 
if __name__ == "__main__":
    a.x()

在这里插入图片描述

答:通过将相关的模块组织成包,使项目结构更为完善和合理。从而增强代码的可维护性和实用性。

以下提供一个可供参考的Python项目结构(仅供参考,没有硬性规定):

|----README/
|    |----readme.txt
|    |----LICENSE.txt
|    |----requirents.txt
|    |----setup.py
|----docs/
|    |----help.html
|    |----quickstart.html
|----test/
|    |----__init__.py
|    |----test_basic.py
|    |----test_advanced.py
|----package/
|    |----__init__.py
|    |----moduleA.py
|    |----moduleB.py
|    |----moduleC.py
|    |----static/
|    |    |----images/
|    |    |----sounds/
|----setup.py
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值