Python——__name__属性、搜索路径和包
测试题(笔试,不能上机哦~):
0. __name__ 属性的含义是什么?
1. 什么时候 __name__ 属性的值是 "__main__"?
2. 如果获得当前 Python 的搜索路径?
3. 如果你不想将相关的模块文件放在当前文件夹内,那最好的选择是?
4. 如果你见到 import urllib.request 语句,那么这个 urllib 是什么?
5. Python 如何区分一个文件夹是普通文件夹还是包?
动动手(一定要自己动手试试哦~):
0. 执行下边 a.py 或 b.py 任何一个文件,都会报错,请改正程序。
注:这道题原理跟上一节课的课后作业(测试题 4、5)类似,如果上节课你搞懂了,这道题应该可以想出解决方案,不要轻易看答案,除非你已经抓破头皮……
- # a.py
- import b
- def x():
- print('x')
- b.y()
- # b.py
- import a
- def y():
- print('y')
- a.x()
- 执行 b.py 引发下边异常:
- >>>
- Traceback (most recent call last):
- File "/Users/FishC/Desktop/b.py", line 1, in <module>
- import a
- File "/Users/FishC/Desktop/a.py", line 1, in <module>
- import b
- File "/Users/FishC/Desktop/b.py", line 6, in <module>
- a.x()
- AttributeError: 'module' object has no attribute 'x'
复制代码
1. 下边是一个 Python 项目的基本结构,请你合理组织它们,便于维护和使用。 鱼C大项目.zip (3.87 KB, 下载次数: 844)
图一时之快先看答案,您将失去一次锻炼的机会!
请先自己动手,再回复查看参考答案!
测试题答案:
0. __name__ 属性的含义是什么?
答:所有模块都有一个 __name__ 属性,__name__ 的值取决于如何应用模块,在作为独立程序运行的时候,__name__ 属性的值是 '__main__',而作为模块导入的时候,这个值就是该模块的名字了。
1. 什么时候 __name__ 属性的值是 "__main__"?
答:请参考上一题答案。
2. 如果获得当前 Python 的搜索路径?
答:我们可以通过 sys 模块中的 path 变量显示出来(不同的机器上显示的路径信息可能不一样)。
- >>> import sys
- >>> sys.path
- ['', 'C:\\Python34\\Lib\\idlelib', 'C:\\WINDOWS\\SYSTEM32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34', 'C:\\Python34\\lib\\site-packages']
复制代码
3. 如果你不想将相关的模块文件放在当前文件夹内,那最好的选择是?
答:放在 site-packages 文件夹,因为它就是用来存放你的模块文件的。
4. 如果你见到 import urllib.request 语句,那么这个 urllib 是什么?
答:是一个包,Python 把同类的模块放在一个文件夹中统一管理,这个文件夹称之为一个包。
urllib 是 Python 负责管理 URL 的包,用于访问网址(后边我们会讲到)。
5. Python 如何区分一个文件夹是普通文件夹还是包?
答:看文件夹中是否有 __init__.py 文件。
必须在包文件夹中创建一个 __init__.py 的模块文件,内容可以为空。可以是一个空文件,也可以写一些初始化代码。这个是 Python 的规定,用来告诉 Python 将该目录当成一个包来处理。
动动手答案:
0. 执行下边 a.py 或 b.py 任何一个文件,都会报错,请改正程序。
答:因为在执行 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()
复制代码
1. 下边是一个 Python 项目的基本结构,请你合理组织它们,便于维护和使用。
答:通过将相关的模块组织成包,使项目结构更为完善和合理。从而增强代码的可维护性和实用性。
以下提供一个可供参考的Python项目结构(仅供参考,没有硬性规定):
鱼C大项目/
|----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