1 模块的介绍
- 在Python中,将自己定义的所有方法和变量都存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。
- 模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py 。
- 模块化指将一个完整的程序分解成一个个的小模块,通过模块组合来搭建一个完整的程序。
- 模块化的优点:方便开发、方便维护、模块可以复用
- 访问模块内容的方式:
– 访问模块中的变量,语法是:模块名.变量名
– 访问模块中的函数,语法是:模块名.函数名
– 访问模块中的对象,语法是:模块名.对象名
示例1:
import sys # import sys 引入 python 标准库中的 sys.py 模块
print('命令行参数如下:')
for i in sys.argv: # sys.argv 是一个包含命令行参数的列表。
print(i)
print('\n\nPython路径为',sys.path,'\n') # sys.path 包含了一个 Python 解释器自动查找所需模块的路径的列表。
2 模块的创建和使用
2.1 模块的导入
-
模块导入的方式:
– 1、在一个模块中引入外部模块的语法:import 模块名,模块名就是py文件。
– 2、如果模块的名字比较长或比较复杂,可以用import……as……语句给模块起别名,语法:import 模块名 as 模块别名
– 3、我们也可以引入模块中指定的部分内容,语法: from 模块名 import 变量,变量…
– 4、为引入模块中指定的部分内容其别名,语法是: from 模块名 import 变量 as 别名
– 5、一个模块的所有内容全都导入到当前的命名空间也是可行的(建议少用),语法:from 模块名 import * ,其效果等价于:import 模块名 -
可以引入同一个模块多次,但是模块的实例只会创建一次,即不管执行了多少次import,一个模块只会被导入一次。
-
当解释器遇到 import 语句,如果模块在当前的搜索路径,模块就会被导入。
-
由于模块需要先导入才能调用,所以模块导入语句如import语句,一般放在代码的最前面。
示例2:
先在当前文件所在的路径创建 module_one模块,模块内容如下:
def print_func(name):
print('hello,',name)
# 导入 module_one模块
import module_one
# module_one模块的print_func函数
module_one.print_func('张三') # 输出结果: hello, 张三
- 执行import语句的时候,Python解释器是根据搜索路径来找到对应的模块文件,搜索路径:
– 搜索路径是一个解释器会先进行搜索的所有目录的列表;
– 搜索路径是由一系列目录名组成的,Python解释器就依次从这些目录中去寻找所引入的模块;
– 搜索路径可以通过定义环境变量的方式来确定;
– 搜索路径是在Python编译或安装的时候确定的,安装新的库应该也会修改;
– 搜索路径被存储在sys模块中的path变量,在Python的交互式解释器IDLE 输入以下代码:
import sys
sys.path
执行结果如下:
['', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\Lib\\idlelib',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\DLLs',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36',
'C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages']
sys.path输出是一个列表,其中第一项是空字符串 ‘’,代表当前目录。
- 在交互式解释器执行得到的结果是Python解释器的目录,对于脚本的话就是运行的脚本所在的目录。
- 注意:如果在当前目录存在一个与准备要引入的模块的同名文件,要引入的模块就会被屏蔽掉,所以在当前目录不要存放与模块名相同的文件。
2.2 __name__属性
- 在一个模块内部都有一个__name__,通过它,我们可以获取模块的名字。
- 如果py文件直接运行时,那么__name__默认等于字符串’__ main__’。
- __name__属性值为 __main__表示当前的模块是主模块,一个程序中只有一个主模块。
示例3:
斐波那契数列(fibonacci)数列模块的内容:
# 斐波那契数列(fibonacci)数列模块
def fib(n): # 定义到n的斐波那契(fibonacci)数列: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 ……
a,b = 0,1 # 等价于 a=0 b=1
while b < n:
print(b,end=' ')
a,b = b,a+b # 这里需要注意 a和b是分开赋值的,即a=b,b=a+b,同时b=a+b的表达式中a的值为执行a=b表达式之前的值
# 可以用语句print(a,b)来观察 a和b的值的变化
print()
def fib2(n): # 返回到 n 的斐波那契数列
result = []
a = 0
b = 1
while b < n:
result.append(b)
a,b = b,a+b
return result
导入斐波那契数列(fibonacci)数列模块:
import fibonacci as fibo
# 调用fibonacci模块的fib函数和fib2函数
fibo.fib(100) # 执行结果:1 1 2 3 5 8 13 21 34 55 89
print(fibo.fib2(1000)) # 输出结果:[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987]
print(__name__) # 输出结果:__main__
print(fibo.__name__) # 输出结果:fibonacci
# 如果需要经常使用一个函数,可以把它赋给一个本地的名称
fib=fibo.fib
fib(100) # 执行结果:1 1 2 3 5 8 13 21 34 55 89
- 一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。
if __name__ == '__main__':
print('程序自身在运行')
else:
print('来自另一个模块')
运行结果为:程序自身在运行
- 注意:
– 1、每个模块都有一个__name__属性,当其值是’main’时,表明该模块自身在运行,否则是被引入。
– 2、name 与 main 底下是双下划线。
2.3 dir()函数
- 内置的函数 dir() 可以找到模块内定义的所有名称,并以一个字符串列表的形式返回。
示例4:
import module_one,fibonacci,sys
lst1=dir(module_one)
print(lst1) # ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'print_func']
lst2=dir(fibonacci)
print(lst2) # ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'fib', 'fib2']
lst3=dir(sys)
print(lst3)
lst3列表的内容:
['__displayhook__', '__doc__', '__excepthook__', '__interactivehook__', '__loader__',
'__name__', '__package__', '__spec__', '__stderr__', '__stdin__', '__stdout__',
'_clear_type_cache', '_current_frames', '_debugmallocstats',
'_enablelegacywindowsfsencoding', '_getframe', '_git', '_home', '_xoptions', 'api_version',
'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'dont_write_bytecode',
'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',
'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_wrapper', 'getallocatedblocks',
'getcheckinterval', 'getdefaultencoding', 'getfilesystemencodeerrors',
'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof',
'getswitchinterval', 'gettrace', 'getwindowsversion', 'hash_info', 'hexversion',
'implementation', 'int_info', 'intern', 'is_finalizing', 'maxsize', 'maxunicode',
'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix',
'set_asyncgen_hooks', 'set_coroutine_wrapper', 'setcheckinterval', 'setprofile',
'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
'thread_info', 'version', 'version_info', 'warnoptions', 'winver']
- 如果没有给定参数,那么 dir()函数会罗列出当前定义的所有名称。
a=[1,2,3]
lst4=dir()
print(lst4)
结果:
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__',
'__loader__', '__name__', '__package__', '__spec__', 'a', 'fibonacci',
'lst1', 'lst2', 'lst3', 'module_one', 'sys']