模块


模块

概念:

模块是一个包含所有你定义的函数和变量的文件,它是一系列功能的集合体分为三大类 ?、内置模块 ?、第三方模块 ?、自定义的模块

一个python文件本身就是一个模块,例如文件名m.py,模块名就叫m

ps:模块有四种形式

?使用python编写的.py文件

?已被编译为共享库或DLL的C或C++扩展

?把一系列模块组织到一起的文件夹

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

使用模块的好处

1、内置与第三方的模块拿来就用,无需定义,可以极大提升开发效率

2、自定义的模块可以将程序的各部分功能提取出来放到同一个模块中共享使用,减少了代码冗余,程序结构更加清晰

模块的使用

导入

import module1[, module2[,... moduleN]
import foo         

首次导入模块会发生三件事情

1、执行foo.py

2、产生foo.py的名称空间,将foo.py运行过程中产生的名字都丢到foo的名称空间中

3、在当前文件中产生有一个名字foo,改名字指向2中产生的名称空间

一个模块只会被导入一次,不管执行了多少次import,都是直接引用首次产生的foo.py名称空间,这样可以防止导入模块被一遍又一遍的执行

# 1、可以以逗号为分隔符在一行导入多个模块

# 建议如下所示导入多个模块

import time

import foo

import m

# 不建议在一行同时导入多个模块

import time,foo,m

# 2、导入模块的规范 优先级
#I. python内置模块
#II. 第三方模块
#III. 程序员自定义模块

# 3、可以将模块名取别名
import foo as f # f=foo
f.get()
f.f1
f.f2
f.f3
# 4、可以在函数中导入模块
# 5、自定义模块的命名应该采用纯小写+下划线的风格

引用

1、当我们引用一个模块下面的值,和当前名称空间名字有重复的时候,模块名.名字是指名道姓的问某一个模块要对应的值,不会与当前名称空间中的名字发生冲突

# 例如 导入一个自定义模块
import foo
x = 1
print(foo.x)

2、无论是查看还是修改操作都是模块本身,与调用位置无关

import foo

x=3333333333
foo.get()
foo.change()
print(x)
print(foo.x)
foo.get()

____name__属性

一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')
    
# 在该模块运行时  程序自身在运行
import using_name
#  当被导入时我来自另一模块
# 每个模块都有一个__name__属性,当其值是'__main__'时,表明该模块自身在运行,否则是被引入。

from...import语句

from语句从模块中导入一个指定的部分到当前命名空间中

from modname import name1[, name2[, ... nameN]]

# 不会将整个模块导入 只会将import后面的功能名引入进来

From...import...导入发生了三件事情

1、产生一个模块的空间

2、运行foo.py将运行过程中产生的名字都丢到模块的名称空间去

3、在当前名称空间拿到一个名字,该名字与模块名称空间中的某一个内存地址

from...import...导入模块在使用时不用加前缀

优点:代码精简了

缺点:容易与当前名称空间混淆

from … import * 语句

from modname import *
# 可以导入模块中所有项目

这种方式进行导入,如果不同模块之间有相同的函数命名,最后导入的会覆盖前面的,也就是说只会调用到最后导入进的函数

在需要导入包中所有模块时,import* 还是有意义的,只需要在 init.py 文件里面将所有模块名定义在列表 ALL 里面,这时候在使用import*只会导入列表内的项目名,但是要以字符串的形式放到列表

print('from the spam.py')

__all__ = ['money',"read1"]
money = 1000

def read1():
    print('spam模块:',money)

def read2():
    print('spam模块')
    read1()

def change():
    global money
    money=0

dir()

内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:

>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
 '__package__', '__stderr__', '__stdin__', '__stdout__',
 '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
 '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
 'call_tracing', 'callstats', 'copyright', 'displayhook',
 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
 'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
 'thread_info', 'version', 'version_info', 'warnoptions']
# 如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称:
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir() # 得到一个当前模块中定义的属性列表
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
>>> a = 5 # 建立一个新的变量 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a # 删除变量名a
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']
>>>

不要循环导入,当有被多个模块使用的项目时最好将其放到,独立共享的模块中,不要循环导入

模块的搜索路径优先级

无论是import还是from...import在导入模块时都涉及到查找问题

优先级:

1、内存(内置模块)

2、硬盘:按照sys.path中内存的文件的顺序依次查找要导入的模块

import sys
值为一个列表,存放了一系列的对文件夹
其中第一个文件夹是当前执行文件所在的文件夹
print(sys.path)

找foo.py就把foo.py的文件夹添加到环境变量中
sys.path.append(r'/Users/linhaifeng/PycharmProjects/s14/day21/aa')
import foo
foo.say()

在导入一个模块时,如果该模块已加载到内存中,则直接引用,否则会优先查找内置模块,然后按照从左到右的顺序依次检索sys.path中定义的路径,直到找模块对应的文件为止,否则抛出异常。sys.path也被称为模块的搜索路径,它是一个列表类型