第051讲:__name__属性、搜索路径和包 | 课后测试题及答案

本文详细解析了Python中模块和包的概念,包括__name__属性的作用、获取Python搜索路径的方法、模块与包的区别及如何正确导入和使用。通过实例演示了如何避免循环导入的问题,并给出了一个合理的项目结构示例。

测试题(笔试,不能上机哦~):

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 任何一个文件,都会报错,请改正程序。

注:这道题原理跟上一节课的课后作业(测试题 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'

答:因为在执行 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 项目的基本结构,请你合理组织它们,便于维护和使用。

鱼C大项目.zip (3.87 KB) link.

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

以下提供一个可供参考的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、付费专栏及课程。

余额充值