python第50课练习—模块:模块就是程序

0、说到底,Python 的模块是什么?

答:模块就是程序。没错,所谓模块就是平时我们写的任何代码,然后保存的每一个 “.py” 结尾的文件,都是一个独立的模块。

1、我们现在有一个 hello.py 的文件,里边有一个 hi() 函数:

def hi():
    print('Hi everyone, i love FishC.com!')

请问我如何在另一个源文件 test.py 里边使用 hello.py 的 hi() 函数呢?

答:只需要在 test.py 中导入 hello 模块(文件名 = 模块名)即可使用 hello.py 中的 hi() 函数。

2、你知道的总共有几种导入模块的方法?

答:我们总共介绍了三种导入模块的方法:

  • 第一种:import 模块名
  • 第二种:from 模块名 import 函数名
  • 第三种:import 模块名 as 新名字

3、曾经我们讲过有办法阻止 from...import * 导入你的“隐私”属性,你还记得是怎么做到的吗?

答:如果你不想模块中的某个属性被 from...import * 导入,那么你可以给你不想导入的属性名称前边加上一个下划线( _ )。不过需要注意的是,如果使用 import ... 导入整个模块,或者显示的使用 import xx._oo 导入某个属性,那么这个隐藏方法就不起作用了。

4、倘若有 a.py 和 b.py 两个文件,内容如下:

# a.py
def sayHi():
    print("嗨!我是A模块!")

# b.py
def sayHi():
    print("嗨!我是B模块!")

那么我在 test.py 文件中执行以下操作,会打印什么结果?

# test.py
from a import sayHi
from b import sayHi

sayHi()

答:会打印“嗨!我是B模块!”,因为第二次导入的 b 模块把 a 模块的同名函数 sayHi() 给覆盖了,这就是所谓命名空间的冲突。所以,在项目中,特别是大型项目中,我们应该避免使用 from...import... ,除非你非常明确不会造成命名冲突。

5、执行下边 a.py 和 b.py 任何一个文件,都会报错,请尝试解释一下此现象。

# a.py
from b import y
def x():
    print('x')

# b.py
from a import x
def y():
    print('y')
image.png

答:这是个循环嵌套导入问题。无论运行 a.py 和 b.py 哪一个文件都会抛出 ImportError 异常。这是因为在执行其中某一个文件(a.py)的加载过程中,会创建模块对象并执行对应的字节码。但当执行第一个语句的时候需要导入另一个文件( from b import y ),因此CPU 会转而去加载另一个文件(b.py)。同理,执行另一个文件的第一个语句( from a import x )恰好也是需要导入之前的的文件(a.py)。此时,之前的文件处于仅导入第一条语句的阶段,因此其对应的字典中并不存在 x , 故抛出 “ImportError: cannot import name x” 异常。

解决方案时直接用 import 语句导入:

# a.py
import b
def x():
    print('x')

# b.py
import a
def y():
    print('y')

a.x()

这题没操作出来.....

练习

0、问大家一个问题:Python 支持常量吗?相信很多鱼油的答案都是否定的,但实际上Python 内建的命名空间是支持一小部分常量的,比如我们熟悉的True,False,None等, 只是Python 没有提供定义常量的直接方式而已。那么这一题的要求是创建一个 const 模块,功能是让 Python 支持常量。

说到这里大家可能还是一头雾水,没关系,我们举个例子。

test.py 是我们的测试代码,内容如下:

# const 模块就是这道题要求我们自己写的
# const 模块用于让Python 支持常量操作

const.NAME = "FishC"
print(const.NAME)

try:
    # 尝试修改变量
    const.NAME = "FishC.com"
except TypeError as Err:
    print(Err)

try:
    # 变量名需要大写
    const.name = 'FishC'
except TypeError as Err:
    print(Err)

执行后的结果是:

>>>
FishC
常量无法改变!
常量名必须由大写字母组成!

在const 模块中我们到底做了什么,使得这个模块这么有魔力呢?大家跟着小甲鱼的提示,一步步来做你就懂了:

  • 提示一:我们需要一个Const 类
  • 提示二:重写Const 类的一个魔法方法,指定当实例对象的属性被修改时的行为。
  • 提示三:检查该属性是否已存在
  • 提示四:检查该属性的名字是否为大写
  • 提示五:细心的鱼油可能发现了,怎么我们这个const 模块导入之后就把它当对象来使用(const.NAME = "FishC")了呢?难道模块也可以是一个对象?没错啦,在Python 中无处不对象,到处都是你的对象。使用以下方法可以将你的模块与类A的对象挂钩。
'''sys.modules 是一个字典,它包含了从Python 开始运行
起,被导入的所有模块。键就是模块名,值就是模块对象'''
import sys
sys.modules[__name__] = A()

额...好像说得有点太多了,大家一定要自己动手先尝试完成噢。
代码清单:

# 该模块用于让Python 支持常量操作
class   Const:
    def __setattr__(self,name,value):
        if name in self.__dict__:
            raise TypeError("常量无法改变!")

        if not name.isupper():
            raise TypeError("常量名必须由大写字母组成!")

        self.__dict__[name] = value

import sys
sys.modules[__name__] = Const()

注: 这题再看看

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 模块和包 一 模块 1 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是...
    go以恒阅读 2,354评论 0 4
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 6,373评论 0 10
  • 一、模块 1、模块和导入 当程序代码量变得相当大、逻辑结构变得非常复杂的时候,我们最好把代码按照逻辑和功能划分成一...
    常大鹏阅读 3,276评论 0 9
  • IO密集型程序、深拷贝和浅拷贝、模块导入、with 语句 1.1 GIL 学习目标 1. 能够说出 GIL 是什...
    Cestine阅读 1,135评论 0 0
  • 这部电影 讲的是 复仇者联盟 的分裂。 第一次分裂,是是否要服从监管体系。 两位大头大哥迅速冒头,以钢铁侠为代表的...
    朱明宽阅读 429评论 0 0

友情链接更多精彩内容