导入pymssql 模块报错_Python学习笔记:模块和包

本文详细介绍了Python中模块和包的使用,包括导入语法、定义模块、模块文档编写和测试,以及包的定义、导入成员和查看模块内容的方法。特别讨论了导入pymssql模块时可能遇到的问题,并提供了解决方案。
摘要由CSDN通过智能技术生成

第九章 模块和包

模块化编程

导入模块的语法

使用import导入模块,主要有两种用法:

  • import 模块名1[as 别名1],模块名2[as 别名2],… : 导入整个模块

  • from 模块名 import 成员名1[as 别名1], 成员名2[as 别名2],…,:导入模块中指定成员

上面两种import语句的区别主要有两点:

  • 第一种import语句导入模块内的所有成员(包括变量、函数、类等);第二种import语句只导入模块内的指定成员(除非使用 from 模块名 import *)

  • 当使用第一种import语句导入模块中的成员时,必须添加模块名或模块别名作为前缀;当使用第二种import语句导入模块中的成员时,无须使用任何前缀,直接使用成员名或成员别名即可

使用import导入模块介绍

1# 导入sys整个模块
2import sys
3# 使用sys模块名作为前缀来访问模块中的成员
4print(sys.argv[0])
5
6输出结果:
7C:\Users\zz\.spyder-py3\temp.py

为模块指定别名,示例:

1# 导入sys整个模块,并指定别名为s
2import sys as s
3# 使用s模块别名作为前缀来访问模块中的成员
4print(s.argv[0])

当指定了别名,就必须使用别名作为前缀,如果仍旧使用模块名,则会报错:

 1# 导入sys整个模块,并指定别名为s
2import sys as s
3# 使用s模块别名作为前缀来访问模块中的成员
4print(s.argv[0])
5
6print("------------")
7# 仍旧使用模块名作为前缀,则会报错
8print(sys.argv[0])
9
10输出结果:
11C:\Users\zz\.spyder-py3\temp.py
12------------
13Traceback (most recent call last):
14
15  File "C:\Users\zz\.spyder-py3\temp.py", line 8, in 16    print(sys.argv[0])1718NameError: name 'sys' is not defined

一次导入多个模块,多个模块之间用逗号隔开,示例:

 1# 导入sys、os两个模块
2import sys,os
3# 使用模块名作为前缀来访问模块中的成员
4print(sys.argv[0])
5# os模块的sep变量代表平台上的路径分隔符
6print(os.sep)
7
8
9输出结果:
10C:\Users\zz\.spyder-py3\temp.py
11\

为多个模块指定别名,示例:

1# 导入sys、os两个模块,并为sys指定别名s,为os指定别名o
2import sys as s,os as o
3# 使用模块别名作为前缀来访问模块中的成员
4print(s.argv[0])
5print(o.sep)

使用from … import 导入模块内指定成员的用法介绍

1# 导入sys模块的argv成员
2from sys import argv
3# 使用导入成员的语法,直接使用成员名访问,不能添加前缀
4print(argv[0])

如果为成员名添加模块名前缀,则会报错,示例:

 1# 导入sys模块的argv成员
2from sys import argv
3# 使用导入成员的语法,直接使用成员名访问
4print(argv[0])
5
6print("--------------------")
7
8# 如果为成员名添加模块名前缀,则会报错
9print(sys.argv[0])
10
11输出结果:
12C:\Users\zz\.spyder-py3\temp.py
13--------------------
14Traceback (most recent call last):
15
16  File "C:\Users\zz\.spyder-py3\temp.py", line 9, in 17    print(sys.argv[0])1819NameError: name 'sys' is not defined

为成员名指定别名,示例:

 1# 导入sys模块的argv成员,并为其指定别名v
2from sys import argv as v
3# 使用导入成员(并指定别名)的语法,直接使用成员的别名访问
4print(v[0])
5
6# 如果指定了别名,就必须使用别名,若仍使用成员名,则会报错
7print(argv[0])
8
9输出结果:
10C:\Users\zz\.spyder-py3\temp.py
11Traceback (most recent call last):
12
13  File "C:\Users\zz\.spyder-py3\temp.py", line 7, in 14    print(argv[0])1516NameError: name 'argv' is not defined

导入多个模块,示例:

1# 导入sys模块的argv,winver成员
2from sys import argv, winver
3# 使用导入成员的语法,直接使用成员名访问
4print(argv[0])
5print(winver)

为多个模块指定别名,示例:

1# 导入sys模块的argv,winver成员,并为其指定别名v、wv
2from sys import argv as v, winver as wv
3# 使用导入成员(并指定别名)的语法,直接使用成员的别名访问
4print(v[0])
5print(wv)
6
7输出结果:
8C:\Users\zz\.spyder-py3\temp.py
93.7

小结:

  • 一旦为模块名或成员名指定了别名,则在程序中必须使用别名,若仍旧使用模块名作为前缀则会报错、若仍旧使用成员名也会报错

  • 使用成员名访问时,不能添加模块名作为前缀,若强制添加模块名作为前缀则会报错

使用from … import语法时也可一次导入指定模块内的所有成员,程序即可使用成员名来使用该模块内的所有成员。(不推荐使用这种语法)示例:

1# 导入sys模块的所有成员
2from sys import *
3# 使用导入成员的语法,直接使用成员的别名访问
4print(argv[0])
5print(winver)
6
7输出结果:
8C:\Users\zz\.spyder-py3\temp.py
93.7

定义模块

模块到底是什么?模块就是python程序,任何python程序都可作为模块导入。对于任何程序,只要导入了模块,即可使用该模块内的所有成员。
module1.py代码:

 1''' 2这是我们编写的第一个模块,该模块包含以下内容: 3my_book:字符串变量 4say_hi:简单的函数 5User:代表用户的类 6'''
7print('这是module 1')
8my_book = '疯狂Python讲义'
9def say_hi(user):
10    print('%s,您好,欢迎学习Python' % user)
11class User:
12    def __init__(self, name):
13        self.name = name
14    def walk(self):
15        print('%s正在慢慢地走路' % self.name)
16    def __repr__(self):
17        return 'User[name=%s]' % self.name

使用模块的好处在于:如果将程序需要使用的程序单元(比如modulel.py定义的say_hi()函数、User类)定义在模块中,后面不管哪个程序,只要导入该模块,该程序即可使用该模块所包含的程序单元,这样就可以提供很好的复用一一导入模块,使用模块,从而避免每个程序都需要重新定义这些程序单元。
模块文件的文件名就是它的模块名,比如module1.py的模块名就是module1。

为模块编写说明文档

在实际开发中也应该为模块编写说明文档,否则,其他开发者都不知道该模块有什么作用,以及包含哪些功能
为模块编写说明文档很简单,只要在模块开始处定义一个字符串直接量即可,可通过模块的doc属性访问文档。module1.py的第一行代码之前添加如下内容,这段内容将作为该模块的说明文档。

1'''2这是我们编写的第一个模块,该模块包含以下内容:3my_book:字符串变量4say_hi:简单的函数5User:代表用户的类6'''

为模块编写测试代码

当模块编写完成之后,可能还需要为模块编写一些测试代码,用于测试模块中的每一个测试单元是否都能正常运行。
希望实现的效果:如果直接使用python命令运行该模块(相当于测试),程序应该执行该模块的测试函数;如果是其他程序导入该模块,程序不应该执行该模块的测试函数。此时可借助于所有模块内置的name__变量进行区分,如果直接使用Python命令来运行一个模块,_name_变量的值为_main_;如果该模块导入被导入其他程序中,_name_变量的值就是模块名。因此,如果希望测试函数只有在使用python命令直接运行时才执行,则可在调用测试函数
时增加判断:只有当_name_属性为__main
时才调用测试函数。为模块增加如下代码即可

 1''' 2这是我们编写的第一个模块,该模块包含以下内容: 3my_book:字符串变量 4say_hi:简单的函数 5User:代表用户的类 6'''
7print('这是module 1')
8my_book = '疯狂Python讲义'
9def say_hi(user):
10    print('%s,您好,欢迎学习Python' % user)
11class User:
12    def __init__(self, name):
13        self.name = name
14    def walk(self):
15        print('%s正在慢慢地走路' % self.name)
16    def __repr__(self):
17        return 'User[name=%s]' % self.name
18
19
20# ===以下部分是测试代码===
21def test_my_book ():
22    print(my_book)
23def test_say_hi():
24    say_hi('孙悟空')
25    say_hi(User('Charlie'))
26def test_User():
27    u = User('白骨精')
28    u.walk()
29    print(u)
30# 当__name__为'__main__'(直接使用python运行该模块)时执行如下代码
31if __name__ == '__main__':
32    test_my_book()
33    test_say_hi()
34    test_User()

使用python module1.py命令来运行该模块,输出结果:

1这是module 1
2疯狂Python讲义
3孙悟空,您好,欢迎学习Python
4User[name=Charlie],您好,欢迎学习Python
5白骨精正在慢慢地走路
6User[name=白骨精]

加载模块

在编译一个python模块之后,如果直接用import或from … import来导入该模块,python通常并不能加载该模块。道理很简单:python怎么知道到哪里去找这个模块呢?
为了让python能找到我们编写(或第三方提供)的模块,可以使用两种方式来告诉它:

  • 使用环境变量

  • 将模块放在默认的模块加载路径之下

使用环境变量

Python将会根据PYTHONPATH环境变量的值来确定到哪里去加载模块。PYTHONPATH环境变量的值是多个路径的集合,这样Python就会依次搜索PYTHONPATH环境变量所指定的多个路径,试图从中找到程序想要加载的模块。在windows平台上设置环境变量
一般建议设置“用户变量”即可,因为用户变量只对当前用户有效,而系统变量对所有用户有效。为了减少自己所做的修改对其他人的影响,故设置用户变量。对于当前用户而言,设置用户变量和系统变量的效果大致相同,不过系统变量的路径排在用户变量的路径之前。
在“变量名”文本框内输入PYTHONPATH,表明将要建立名为PYTHONPATH的环境变量:在“变量值”文本框内输入 .;d:\python_module,这就是该环境变量的值,该值其实包含了两条路径(分号为分隔符),第一条路径为一个点(.),这个点代表当前路径,表明当运行Python程序时,Python总能从当前路径加载模块:第二条路径为d:\python_module,表明当运行Python程序时,Python总能从d:\python_module加载模块。
在成功设置了上面的环境变量之后,接下来只要把前面定义的模块(Python程序)放在与当前所运行Python程序相同的路径中(或放在d:\python_module路径下),该模块就能被成功加载了。
提示:设置完环境变量后,需要重启 spyder 编辑器,让spyder重新加载环境变量的值。

 1# 导入module1,并指定其别名为md
2import module1 as md
3print(md.my_book)
4md.say_hi('Charlie')
5user = md.User('孙悟空')
6print(user)
7user.walk()
8
9输出结果:
10这是module 1
11疯狂Python讲义
12Charlie,您好,欢迎学习Python
13User[name=孙悟空]
14孙悟空正在慢慢地走路

默认的模块加载路径

python默认的模块加载路径由sys.path变量代表,可通过在交互式解释器中输入如下命令来查看:

 1import sys,pprint
2
3pprint.pprint(sys.path)
4['C:\\Users\\zz',
5 'D:\\Python\\python_module',
6 'D:\\6.CommonTools\\anaconda2\\envs\\python37\\python37.zip',
7 'D:\\6.CommonTools\\anaconda2\\envs\\python37\\DLLs',
8 'D:\\6.CommonTools\\anaconda2\\envs\\python37\\lib',
9 'D:\\6.CommonTools\\anaconda2\\envs\\python37',
10 '',
11 'D:\\6.CommonTools\\anaconda2\\envs\\python37\\lib\\site-packages',
12 'D:\\6.CommonTools\\anaconda2\\envs\\python37\\lib\\site-packages\\win32',
13 'D:\\6.CommonTools\\anaconda2\\envs\\python37\\lib\\site-packages\\win32\\lib',
14 'D:\\6.CommonTools\\anaconda2\\envs\\python37\\lib\\site-packages\\Pythonwin',
15 'D:\\6.CommonTools\\anaconda2\\envs\\python37\\lib\\site-packages\\IPython\\extensions',
16 'C:\\Users\\zz\\.ipython']

如果要打印的内容很多,使用pprint可以显示更友好的打印结果。
通常来说,我们应该将python的扩展模块添加在 lib\site-packages 路径下,它专门用于存放python的扩展模块和包。
下面编写一个python模块文件(print_shape.py),并将该文件复制到  lib\site-packages\ 目录下面,就相当于为python扩展了一个 print_shape 模块,这样任何python程序都可使用该模块,示例:

 1# coding: utf-8
2''' 3简单的模块,该模块包含以下内容 4my_list:保存列表的变量 5print_triangle: 使用星号打印三角形的函数 6'''
7my_list = ['Python', 'Kotlin', 'Swift']
8def print_triangle(n):
9    '''使用星号打印一个三角形'''
10    if n <= 0:
11        raise ValueError('n必须大于0')
12    for i in range(n):
13        print(' ' * (n - i - 1), end='')
14        print('*' * (2 * i + 1), end='')
15        print('')
16
17# ====以下是测试代码====
18def test_print_triangle():
19    print_triangle(3)
20    print_triangle(4)
21    print_triangle(7)
22if __name__ == '__main__': test_print_triangle()

交互式解释器中测试该模块:

 1(base) C:\Users\zz>conda activate python37
2
3(python37) C:\Users\zz>python
4Python 3.7.9 (default, Aug 31 2020, 17:10:11) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
5Type "help", "copyright", "credits" or "license" for more information.
6>>> import print_shape
7>>> print(print_shape.__doc__)
8
9简单的模块,该模块包含以下内容
10my_list:保存列表的变量
11print_triangle: 使用星号打印三角形的函数
12
13>>> print_shape.print_triangle.__doc__
14'使用星号打印一个三角形'
15>>> print_shape.my_list[1]
16'Kotlin'
17>>> print_shape.print_triangle(5)
18    *
19   ***
20  *****
21 *******
22*********
23>>> 

从上面可以看到,程序通过模块名前缀访问my_list变量,输出了该变量的第二个元素。

导入模块的本质

定义一个新的模块(fk_module.py),该模块比较简单,示例:

1'一个简单的测试模块: fkmodule'
2print("this is fk_module")
3name = 'fkit'
4
5def hello():
6    print("Hello, Python")

接下来,在相同路径下定义如下程序来使用该模块,示例:

1import fk_module
2
3print("================")
4# 打印fk_module的类型
5print(type(fk_module))
6print(fk_module)
7print(fk_module.name)
8print(fk_module.hello)

输出结果:

1this is fk_module
2================
3<class 'module'>4<module 'fk_module' from 'C:\\Users\\zz\\.spyder-py3\\fk_module.py'>5fkit67

使用“import fk_module”导入模块的本质就是:将fk_module.py中的全部代码加载到内存井执行,然后将整个模块内容赋值给与模块同名的变量(fk_module),该变量的类型是module,而在该模块中定义的所有程序单元都相当于该module对象的成员。
再试试使用from … import 语句来执行导入,示例:

1from fk_module import name, hello
2
3print("================")
4print(name)
5print(hello)
6# 打印fk_module
7print(fk_module)

输出结果:

 1this is fk_module
2================
3fkit
40x00000157712CE678> 5Traceback (most recent call last): 6 7  File "C:\Users\zz\.spyder-py3\temp.py", line 7, in  8    print(fk_module) 910NameError: name 'fk_module' is not defined

使用 "from fk_module import name, hello" 导入模块中成员的本质是:将fk_module.py中的全部代码加载到内存并执行,然后只导入指定变量、函数等成员单元,并不会将整个模块导入,因此上面程序在输出fk_module时将看到错误提示:name 'fk_module' is not defined
在导入模块后,可以在模块文件所在目录下看到一个名为"pycache"的文件夹,打开该文件夹,可以看到Python为每个模块都生成一个*.cpython-36.pyc文件,比如Python为fk_module模块生成一个fk_module.cpython-36.pyc文件,该文件其实是Python为模块编译生成的字节码,用于提升该模块的运行效率。

模块的all变量

在默认情况下,如果使用“from 模块名 import *”这样的语句来导入模块,程序会导入该模块中所有不以下画线开头的程序单元,这是很容易想到的结果。
有时候模块中虽然包含很多成员,但并不希望每个成员都被暴露出来供外界使用,此时可借助于模块的all__变量,将变量的值设置成一个列表,只有该列表中的程序单元才会被暴露出来。
定义一个包含__all
变量的模块(all_module.py)

 1'测试__all__变量的模块'
2
3def hello():
4    print("Hello, Python")
5def world():
6    print("Pyhton World is funny")
7def test():
8    print('--test--')
9
10# 定义__all__变量,指定默认只导入hello和world两个程序单元
11__all__ = ['hello', 'world']

示范模块中all变量的用处

 1# 导入all_module模块内所有成员
2from all_module import *
3hello()
4world()
5test() # 会提示找不到test()函数
6
7输出结果:
8Hello, Python
9Pyhton World is funny
10Traceback (most recent call last):
11
12  File "C:\Users\zz\.spyder-py3\temp.py", line 5, in 13    test() # 会提示找不到test()函数1415NameError: name 'test' is not defined

上面程序显示,只导入了all__变量所列的程序单元,函数test()默认没有被导入。_all_变量的意义在于为模块定义了一个开放的公共接口。通常来说,只有_all_变量列出的程序单元,才是希望该模块被外界使用的程序单元。因此,为模块设置_all_变量还是比较有用的。比如一个实际的大模块可能包含了大量其他程序不需要使用的变量、函数和类,那么通过_all_变量即可把它们自动过滤掉,这还是非常酷的。如果确实希望程序使用模块内__all列表之外的程序单元,有两种解决方法:

  • 第一种是使用“import 模块名”来导入模块。在通过这种方式导入模块之后,总可以通过模块名前缀(如果为模块指定了别名,则使用模块的别名作为前缀)来调用模块内的成员。

  • 第二种是使用"from 模块名 import 程序单元”来导入指定程序单元。在这种方式下,即使想导入的程序单元没有位于all列表中,也依然可以导入。

使用包

对于一个需要实际应用的模块而言,往往会具有很多程序单元,包括变量、函数和类等,如果将整个模块的所有内容都定义在同一个Python源文件中,这个文件将会变得非常庞大,显然并不利于模块化开发。

什么是包

为了更好地管理多个模块源文件,python提供了包的概念。那么什么是包呢?

  • 从物理上看,包就是一个文件夹,在该文件夹下包含了一个init.py文件,该文件夹可用于包含多个模块源文件

  • 从逻辑上看,包的本质依然是模块

包的作用是包含多个模块,但包的本质依然是模块,包可用于包含包。

定义包

定义包很简单,主要有两步:

  1. 创建一个文件夹,该文件夹的名字就是该包的包名

  2. 在该文件夹内添加一个 init.py文件即可

下面定义一个非常简单的包。先创建一个 first_package 文件夹,在该文件夹中添加一个 init.py 文件,该文件内容如下:

1'''2这是学习包的第一个示例3'''
4print('this is first_package')

该文件开始部分的字符串是该包的说明文档。通过如下程序使用该包,示例:

 1# 导入first_package包(模块)
2import first_package
3
4print('==========')
5print(first_package.__doc__)
6print(type(first_package))
7print(first_package)
8
9
10
11输出结果:
12this is first_package
13==========
14
15这是学习包的第一个示例
16
17<class 'module'>18<module 'first_package' from 'C:\\Users\\zz\\.spyder-py3\\first_package\\__init__.py'>19

再次强调,包的本质就是模块,因此导入包和导入模块的语法完全相同。
从上面的输出结果可以看出,在导入first_package包时,程序执行了该包所对应的文件夹下的init__.py;从倒数第二行输出可以看到,包的本质就是模块;从最后一行输出可以看到,使用"import first_package"导入包的本质就是加载并执行该包下的_init_.py文件,然后将整个文件内容赋值给与包同名的变量,该变量的类型是module。
与模块类似的是,包被导入之后,会在包目录下生成一个_pycache_一文件夹,并在该文件夹内为包生成一个_init_.cpython-37.pyc文件。
由于导入包就相当于导入该包下的_init_.py文件,因此我们完全可以在_init_.py文件中定义变量、函数、类等程序单元,但实际上往往并不会这么做。想一想原因是什么?包的主要作用是包含多个模块,因此_init_.py文件的主要作用就是导入该包内的其他模块。下面再定义一个更加复杂的包,在该包下将会包含多个模块,并使用__init
.py文件来加载这些模块。
新建一个 fk_package 包,包含三个模块文件:

  • arithmetic_chart.py

1def print_multiple_chart(n):
2    '打印乘法口角表的函数'
3    for i in range(n):
4        for j in range(i + 1):
5            print('%d * %d = %2d' % ((j + 1) , (i + 1) , (j + 1)* (i + 1)), end='  ')
6        print('')
  • billing.py

1class Item:
2    '定义代表商品的Item类'
3    def __init__(self, price):
4        self.price = price
5    def __repr__(self):
6        return 'Item[price=%g]' % self.price
  • print_shape.py

 1def print_blank_triangle(n):
2    '使用星号打印一个空心的三角形'
3    if n <= 0:
4        raise ValueError('n必须大于0')
5    for i in range(n):
6        print(' ' * (n - i - 1), end='')
7        print('*', end='')
8        if i != n - 1:
9            print(' ' * (2 * i - 1), end='')
10        else:
11            print('*' * (2 * i - 1), end='')
12        if i != 0: 
13            print('*')
14        else:
15            print('')

init.py 文件暂时为空,不用编写任何内容。
这意味着:fk_package 包(也是模块)总共包含这三个模块。在这种情况下,这三个模块就相当于fk_package 包的成员。

导入包内成员

 1# 导入fk_package包,实际上就是导入包下__init__.py文件
2import fk_package
3# 导入fk_package包下的print_shape模块,
4# 实际上就是导入fk_package目录下的print_shape.py
5import fk_package.print_shape
6# 实际上就是导入fk_package包(模块)导入print_shape模块
7from fk_package import billing
8# 导入fk_package包下的arithmetic_chart模块,
9# 实际上就是导入fk_package目录下的arithmetic_chart.py
10import fk_package.arithmetic_chart
11
12fk_package.print_shape.print_blank_triangle(5)
13im = billing.Item(4.5)
14print(im)
15fk_package.arithmetic_chart.print_multiple_chart(5)
16
17
18输出结果:
19    *
20   * *
21  *   *
22 *     *
23*********
24Item[price=4.5]
251 * 1 =  1  
261 * 2 =  2  2 * 2 =  4  
271 * 3 =  3  2 * 3 =  6  3 * 3 =  9  
281 * 4 =  4  2 * 4 =  8  3 * 4 = 12  4 * 4 = 16  
291 * 5 =  5  2 * 5 = 10  3 * 5 = 15  4 * 5 = 20  5 * 5 = 25  
e673b0456bd103c8bbff7b94a0ed2990.png
28f28003b0ec23a673698e6e0e12de8e.png
 1# 从当前包导入print_shape模块
2from . import print_shape
3# 从.print_shape导入所有程序单元到fk_package中
4from .print_shape import *
5# 从当前包导入billing模块
6from . import billing
7# 从.billing导入所有程序单元到fk_package中
8from .billing import *
9# 从当前包导入arithmetic_chart模块
10from . import arithmetic_chart
11# 从.arithmetic_chart导入所有程序单元到fk_package中
12from .arithmetic_chart import *
4b1bf6b76cfbf86fe91403e4dc72e9e2.png
1# 导入fk_package包,实际上就是导入包下__init__.py文件
2import fk_package
3
4# 直接使用fk_package前缀即可调用它所包含的模块内的程序单元。
5fk_package.print_blank_triangle(5)
6im = fk_package.Item(4.5)
7print(im)
8fk_package.print_multiple_chart(5)

输出结果:

 1    *
2   * *
3  *   *
4 *     *
5*********
6Item[price=4.5]
71 * 1 =  1  
81 * 2 =  2  2 * 2 =  4  
91 * 3 =  3  2 * 3 =  6  3 * 3 =  9  
101 * 4 =  4  2 * 4 =  8  3 * 4 = 12  4 * 4 = 16  
111 * 5 =  5  2 * 5 = 10  3 * 5 = 15  4 * 5 = 20  5 * 5 = 25  

上面粗体字代码是导入fk_package包,导入该包的本质就是导入该包下的init__.py文件。而__init.py文件又执行了导入,它们会把三个模块内的程序单元导入fk_package包中,因此程序的下面代码可使用fk_package.前缀来访问三个模块内的程序单元。

查看模块内容

在导入模块之后,开发者往往需要了解模块包含哪些功能,比如包含哪些变量、哪些函数、哪些类等,还希望能查看模块中各成员的帮助信息,掌握这些信息才能正常地使用该模块。

模块包含什么

为了查看模块包含什么,可以通过如下两种方式:

  • 使用dir()函数 (返回模块或类所包含的全部程序单元,包括变量、函数、类和方法等)

  • 使用模块本身提供的all变量

 1import string
2
3dir(string)
4Out[24]: 
5['Formatter',
6 'Template',
7 '_ChainMap',
8 '_TemplateMetaclass',
9 '__all__',
10 '__builtins__',
11 '__cached__',
12 '__doc__',
13 '__file__',
14 '__loader__',
15 '__name__',
16 '__package__',
17 '__spec__',
18 '_re',
19 '_string',
20 'ascii_letters',
21 'ascii_lowercase',
22 'ascii_uppercase',
23 'capwords',
24 'digits',
25 'hexdigits',
26 'octdigits',
27 'printable',
28 'punctuation',
29 'whitespace']

很明显,该模块内有大量以下划线开头的程序单元,其实这些程序单元并不希望被其他程序使用,因此列出这些程序单元意义不大,可以使用列表推导式过滤掉,示例:

 1[e for e in dir(string) if not e.startswith('_')]
2Out[25]: 
3['Formatter',
4 'Template',
5 'ascii_letters',
6 'ascii_lowercase',
7 'ascii_uppercase',
8 'capwords',
9 'digits',
10 'hexdigits',
11 'octdigits',
12 'printable',
13 'punctuation',
14 'whitespace']

也可通过该模块的all__变量来查看模块内的程序单元(有些模块不提供__all变量,只能使用上面列表推导式来查看),如下

 1tring.__all__
2Out[26]: 
3['ascii_letters',
4 'ascii_lowercase',
5 'ascii_uppercase',
6 'capwords',
7 'digits',
8 'hexdigits',
9 'octdigits',
10 'printable',
11 'punctuation',
12 'whitespace',
13 'Formatter',
14 'Template']

使用doc属性查看文档

使用help()函数之所以能查看到程序单元的帮助信息,其实完全是因为该程序单元本身有文档信息,也就是有doc__属性。换句话说,使用help()函数查看的其实就是程序单元的__doc属性值。
提示:Python库的参考文档:https://docs.python.org/3/library/index.html

使用file属性查看模块的源文件路径

通过模块的file__属性即可查看到指定模块的源文件路径。开发者完全可以根据路径打开查看该模块的全部源代码。
需要说明的是,并不是所有模块都是使用Python语言编写的,有些与底层交互的模块可能是用C语言编写的,而且是C程序编译之后的效果,因此这种模块可能没有__file
属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值