Python学习基础笔记四十四——模块

1、看一个例子:

创建一个demo.py文件:

print('in demo.py')


def hello():
    print('in hello function')

然后我们在另外一个文件中import这个demo文件:

import demo


# 调用demo.py文件中的hello()函数
demo.hello()

注意,demo后面没有py。 

运行,产生结果:

Python学习基础笔记四十四——模块_第1张图片

模块:就是包含了Python定义和声明的文件,文件名就是模块名称加上.py的后缀。

import加载的模块分为4个通用类别:

1)使用python编写的代码(.py文件)

2)已被编译为共享库或DLL的C或C++扩展;

3)包好一组模块的包;

4)使用C编写并链接到python解释器的内置模块;

2、为什么使用模块?

我们退出python解释器,然后再重新进入,之前定义的函数或变量都将丢失,因此我们通常将程序写到文件中便可永久地保存下来,需要的时候就通过python test.py的方式去执行,此时test.py被称为脚本script。

随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分为一个个的文件,这样程序的结构更清晰,方便管理。这样,我们不仅仅可以将这些文件当脚本去执行,还可以把他们当作模块来导入到其他的模块中,实现了功能的重复利用。

3、如何使用模块:

import语句。

1)模块可以包含执行的语句和函数的定义。它们只在模块名第一次遇到import语句的时候才被执行,import语句可以在程序中的任意位置使用,可针对同一个模块import多次,为了防止重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载到内存中的模块对象的一次引用,不会再重新执行模块中的语句。

import sys

print(sys.modules)

Python学习基础笔记四十四——模块_第2张图片

 2)我们可以从sys.modules中找到当前已加载的模块,sys.module是一个字典,内部包含模块名和模块对象的映射, 改字典决定了导入模块时是否要重新导入。

3)名称空间:每个模块都有自己的名称空间,定义在这个模块中的函数,把这个模块的命名空间当作全局名称空间,这样,我们在编写自己的模块的时候,就不用担心我们定义在自己模块中的全局变量会在被导入时,与使用者全局变量冲突。

4、import文件做的完整流程:

1)先从sys.modules里查看是否已经被导入;

2)如果没有被导入,就依据sys.path路径取寻找路径;(导入包寻找路径)

3)找到了就导入;

2)创建模块的命名空间;

3)执行文件,把文件的名字都放到命名空间中;

5、为模块起别名:

import time as t

print(t.time())

别名的应用场景:

#mysql.py
def sqlparse():
    print('from mysql sqlparse')
#oracle.py
def sqlparse():
    print('from oracle sqlparse')

#test.py
db_type=input('>>: ')
if db_type == 'mysql':
    import mysql as db
elif db_type == 'oracle':
    import oracle as db

db.sqlparse() 
复制代码

示例用法1

 为已经导入的模块起别名的方式对编写可扩展的代码很有用,假设有两个模块xmlreader.py和csvreader.py,它们都定义了函数read_data(filename):用来从文件中读取一些数据,但采用不同的输入格式。可以编写代码来选择性地挑选读取模块,例如

if file_format == 'xml':
     import xmlreader as reader
elif file_format == 'csv':
     import csvreader as reader
data=reader.read_date(filename)

提高了代码的兼容性。

注意的是:重命名之后,原来的module的名称就不能使用了,只能使用重命名的名称。

6、一行导入多个模块:

import time os re

我们在实际工作中,不建议这么使用。建议是分开写,以后注释也非常方便,代码也非常方便阅读。

在文件的开头部分,将所有的导入模块都列出来。

编码规则,导入模块也分先后顺序:

1)导入内置模块;

2)扩展的模块;例如:django模块

3)自定义的模块;

7、from...import...

1)import my_module, 会将源文件的名称空间my_module带到当前的名称空间中,使用时必须是my_module.名字的方式。

而frome语句相当于import, 也会创建新的命名空间,但是将my_module中的名字直接导入到当前的命名空间中,在当前的命名空间中,直接使用函数名字就可以了。

这两种方式各有千秋。

#测试一:导入的函数read1,执行时仍然回到my_module.py中寻找全局变量money
#demo.py
from my_module import read1
money=1000
read1()
'''
执行结果:
from the my_module.py
spam->read1->money 1000
'''

#测试二:导入的函数read2,执行时需要调用read1(),仍然回到my_module.py中找read1()
#demo.py
from my_module import read2
def read1():
    print('==========')
read2()

'''
执行结果:
from the my_module.py
my_module->read2 calling read1
my_module->read1->money 1000
'''

2)如果有重名的read1和read2, 那么会有覆盖的效果。

我们使用from * import read1, 那在本地的命名空间中全局就能使用read1, 但是,如果我们在本地定义了一个read1函数,就不能在本地命名空间中使用到这个read1函数了,会有一个覆盖的效果。

3)from demo import money, 这是一个变量。

需要特别强调的一点:python中的变量赋值不是一种存储操作,而只是一种绑定关系。

4)from demo import *   这种方式不太安全,可能会覆盖掉你之前已定义的名字,可读性极差,在交互环境中导入是没有问题的。

# demo.py
print('in demo.py')

money = 100


def hello():
    return 'in hello function', 100

# 01homework.py
__all__ = ['money']     # 这个地方做了限制,只能有money这个变量, 这个__all__只跟这个*有关联

from demo import *

print(money)
ret = read()           # 在pycharm中,read有红色的波浪线显示read函数名无效
print(ret)

结果:

Python学习基础笔记四十四——模块_第3张图片

 5)也支持重命名:

from demo import read as r

6)支持导入多行:

from demo import (read1,
                  read2,
                  money)

7)如果在demo.py文件中的变量名字前加_, 即_money, 则from demo import *, 则_money变量不能被导入。

8、把模块当着脚本执行:
我们可以通过模块的全局变量__name__来查看模块名:

当作脚本运行:

__name__ 等于'__main__'

当作模块导入:

__name__ = 模块名

作用:用来控制.py文件在不同的应用场景下执行不同的逻辑。

def fib(n):   
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

if __name__ == "__main__":
    print(__name__)
    num = input('num :')
    fib(int(num))

再看一个例子:

# demo.py 文件
def login():
    print('Doing login function!')


def hello():
    print('in read1', money)


def hello2():
    print('in read2')


money = 100
print('in demo.py')

# 如果直接执行的是当前的py文件,,那么__name__的值就等于__main__,
# 如果是在别的模块文件中导入引用该文件模块,那__name__的值就等于模块名,
# 那我们通过这种机制,就给程序两种状态。在别的模块执行,那下面的这段程序就不执行。
if __name__ == '__main__':     
    ret = login()
    print(ret)

9、总结:

所有的模块导入,都应该尽量写在代码的开头部位。顺序:内置模块、拓展模块、自定义模块。

import 模块名:

模块名.变量名和本地的同名变量名不会发生冲突

import 模块名 as 重命名的模块名, 提高代码的兼容性,完成相同的功能,使用相同的名字,例子:数据库和文件

import 模块名1 模块名2 模块名3   不推荐这种写法

from 模块名 import 变量名:

直接使用变量名,就可以完成操作

如果本文件中有相同的变量名就发生冲突,这个要注意的。

from 模块名 import 变量名 as 重命名的变量名

from 模块名 import 变量名1 变量名2 变量名3

from 模块名 import * 将模块中的所有变量名都放到内存中。你都不知道模块中有哪些名字,容易导致冲突。

from 模块名 import * 和__all__是一对。没有这个变量,会导入所有的名字,如果有all,只导入,只导入all列表中的变量。

你可能感兴趣的:(Python,python)