python练习生|这些模块小知识,你都get了吗?(模块的简介、创建、导入(使用)方式、__name__、__main__、迭代器、生成器
一.模块的简介
1.什么是模块
- 模块(module): 模块是能够单独命名并具有一定功能的代码块(程序语句)的集合。简单的来说,python中一个 .py文件 就是一个 模块 。
2.模块化的优点
我们将代码进行模块化具有以下优点:
- 便于开发和代码的维护
- 可以进行模块的复用,提高编写代码的效率
二.模块的创建与导入(使用)
1.模块的创建
- 我们之前已经说了,一个 .py文件就是一个模块 。
- 但是,我们也要清楚一些创建的注意事项:
- 我们所创建模块的模块名要遵循Python变量命名规范,不要使用中文或特殊字符来命名。
-
模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行 import abc ,若成功则说明系统存在此模块。
- 一般一个完整的模块应包含:
#一般一个完整模块包含:
#变量
a = 1
#函数
def fn():
pass
#类
class person():
pass
#判断
if
2.模块的导入(使用)
模块的导入方式有以下几种,由我慢慢道来。
- 首先先把测试模块放上去
(1).方法一:import 模块名
#在模块中导入外部模块
#方式一 import 模块名(其实就是.py的文件名)
#注意,我们可以导入同一个模块多次,但是模块只会执行一次
import test_m
# import test_m
# import test_m
print(test_m)
- 值的一提的是,你可以导入同一个模块多次,但是该模块只会执行一次
(2).方法二:import 模块名 as 模块别名
#方式二 import 模块名 as 模块别名
import test_m as test
print(test)
- 导入模块test_m 内部代码
#在模块中定义变量
a = 1
b = 2
#在模块中定义函数
def test1():
print('我是test_m模块中的函数fn')
#测试 test1 能够正常运行
# test1()
#在模块中定义类
class speak():
def __init__(self):
self._name = '李云龙'
#测试 speak 能够正常运行
# a = speak()
# print(a._name)
(3).方法三:from 模块名 import 变量,变量,变量…
# 由于前两种方法所输出的是模块中的所有代码,所以,为了只调用模块中局部功能我们可以用方法三
# 方法三 from 模块名 import 变量,变量,变量
from test_m import test1,speak
test1()
a = speak()
print(a._name)
(4).方法四:from 模块名 import *
#方法四 from 模块名 import *
from test_m import *
a = speak()
print(a._name)
- 值得一提的是, 方法四 的导入模块方式没有方法一的友好一些,为什么会这样说呢?待我举例说明
- 如果主模块与导入模块具有相同名称的功能函数,输出的结果会是什么呢?
# 在主模块中定义函数
# 方法四的例子
def test1():
print('我是test_module模块中的函数fn')
#方法四没有 import 模块名 友好,举例如下:
# 如果主模块(test_module)中有和导入模块(test_m)相同功能名称的情况,则会运行导入模块的函数,相当于是对主模块相同名称的函数进行了覆盖
from test_m import *
test1()
- 由图我们可以看出,我们导入的模块所调用的功能函数把原本主模块中的相同名称的函数进行了“覆盖”。
- 有人可能会说,如果我把柱模块的函数放在下方,不就可以了吗,其实,把主模块放在下方,相当于是对模块进行了无效的导入。占用系统内存。
- 针对主模块与导入模块调用函数同名的情况,我们可以用方法五处理。
(5).方法五:from 模块名 import 变量 as 别名
#当主模块和导入模块有相同功能名称的情况,则可以用方法五来处理
#方法五 from 模块名 import 变量 as 别名
from test_m import test1 as test2
test1()
test2()
三.访问模块属性的语法
- 模块test_m内部代码
#在模块中定义变量
a = 1
b = 2
#在模块中定义函数
def test1():
print('我是test_m模块中的函数fn')
#在模块中定义类
class speak():
def __init__(self):
self._name = '李云龙'
- 在主模块中,访问模块变量的语法是: 模块名.变量
- 在主模块中,访问模块函数的语法是: 模块名.函数名
- 在主模块中,访问模块类的语法是: 模块名.对象名
import test_m as test
# 在主模块中,访问模块变量的语法是: 模块名.变量
print(test.a)
# 在主模块中,访问模块函数的语法是: 模块名.函数名
test.test1()
# 在主模块中,访问模块类的语法是: 模块名.对象名
a = test.speak()
print(a._name)
四.关于__name__和__main__的理解
1.浅谈__name__和__main__的理解
-
关于__name__的一些事: 每一个模块内部,都有一个__name__ ,我们可以通过这个特殊方法获取模块的名字。
-
关于__main__的一些事:如果 .py文件 直接运行(如果在这个 模块 内部直接运行),那么__name__是默认等于字符串 __main__的。
-
__name__属性值为__main__的模块是主模块。⼀个程序中只有⼀个主模块。
此处分割线
导入模块test_m的内部代码
print(__name__)
import test_m as test
print(test)
import test_m as test # 导入模块test_m 命别名为 test,直接在控制台输出结果 test_m
print(test) # 在控制台输出的结果是模块的名字所指向的路径
print(__name__) # __name__ 是内置函数,用于表示当前模块的名字,而我们的主文件都叫做__main__
2.__name__和__main__的整体用法
(1).if name == “main”: 的用意
-
其实主要说的是:
if __name__ == "__main__":
这行代码的意义与用法。 -
举例如下:
-
这是模块 test_m (导入的模块)
a = 2
def speak():
print('我是test_m的函数speak,我引入了变量:%f'%a)
#这里调用函数speak是为了检查代码输出是否正确
speak()
#从test_m 模块中调用变量a
from test_m import a
def add():
b = 3
print('我是test_module的函数,我执行了加法%f'%(a+b))
add()
- 由上图和结果我们可得知,我们在进行模块参数调用时, 测试模块test_m中的speak函数 ,也跟着被一起调用,然后输出了。但是,我们并不像让speak函数在调用时被输出。
-代码改进如下: - 我们对 测试模块test_m 中的代码进行了改进
a = 2
def speak():
print('我是test_m的函数speak,我引入了变量:%f'%a)
#加入了 if __name__ == "__main__": 这行代码。
#这行代码的目的是判断如果当前文件为主文件(主模块),则执行下面的操作,如果不是,则不执行。
if __name__ == "__main__":
speak()
- 我们在 测试模块test_m ,中,加了一行判断语句:
if __name__ == "__main__":
- 这行代码的目的就是来判断,如果当前文件为主文件(主模块),则执行下面的操作,如果不是,则不执行。
下面看我们的 test_module 模块进行 测试模块test_m 中的 变量 a 调用后输出的结果。
#从test_m 模块中调用变量a
from test_m import a
def add():
b = 3
print('我是test_module的函数,我执行了加法%f'%(a+b))
add()
五.迭代器和生成器
1.迭代器(iterator)
- 迭代器:访问元素的一种形式
(1).迭代器的特点
- 可以记住遍历位置的对象
- 迭代器从序列当中第一个元素进行访问,直到所有的元素被访问完,结束访问。
- 主要用到 iter()、next() 这两个函数
#迭代器iterator
lst = [1,2,3,4,5]
myiter = iter(lst)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
- 细心的你一定能够发掘,这样进行输出太过繁琐,我们下面我们进行代码的优化。
lst = [1,2,3,4,5]
myiter = iter(lst)
for i in myiter: #迭代数据结构
print(i)
2.生成器(generator)
- 在python中使用 yield 关键字,我们称之为 生成器或生成器函数
- 生成器函数与普通函数的区别:生成器函数与普通函数不同之处是生成器函数返回的是一个迭代器函数,只用于迭代作用。
- next()方法,从当前位置继续访问。
#生成器yield
def num():
print('1')
yield 10
print('2')
yield 20
print('3')
yield 30
print('4')
yield 40
n = num()
print(type(n)) # <class 'generator'>
# next(n)
print('返回:',next(n))
print('返回:',next(n))
print('返回:',next(n))
- 其实 生成器 的返回值你可以参考 return ,只不过,return返回后,整个程序就已经结束。然而,yield 返回后,会通过next()寻找下一个yiled。