文章目录
一,模块:
1,找到模块
1.1.1.让Python去找目录
①(不常用)这里假设这个文件存储在目录C:\python(Windows)或~/python(UNIX/macOS)中。要告诉解释器去哪里查找这个模块,可执行如下命令(以Windows目录为例):
>>> import sys
>>> sys.path.append('C:/python')
这告诉解释器,除了通常将查找的位置外,还应到目录C:\python中去查找这个模块。这样做后,就可以导入这个模块了(它存储在文件C:\python\hello.py中)。
>>> import hello
Hello, world
②将模块所在的目录包含在环境变量 PYTHONPATH 中
环境变量并不是Python解释器的一部分,而是操作系统的一部分。大致而言,它们类似
于Python变量,但是在Python解释器外面设置的。如果你使用的是 bash shell(在大多数类UNIX系统、macOS和较新的Windows版本中都有),就可使用如下命令将 ~/python 附加到环境变量 PYTHONPATH 末尾:
export PYTHONPATH=$PYTHONPATH:~/python
如果要对所有启动的shell都执行这个命令,可将其添加到主目录中的.bashrc文件中。关
于如何以其他方式编辑环境变量,请参阅操作系统文档。
还可使用路径配置文件。这些文件的扩展名为.pth,位于一些特殊目录中,包含要添加到 sys.path 中的目录,请参阅有关模块 site的标准库文档
1.1.2.把模块放到目录中
>>> import sys,pprint
>>> pprint.pprint(sys.path) #pprint能更好的打印字符
['',
'D:\\PY\\Lib\\idlelib',
'D:\\PY\\python37.zip',
'D:\\PY\\DLLs',
'D:\\PY\\lib',
'D:\\PY',
'D:\\PY\\lib\\site-packages']
可以把模块放到以上目录中,这样就可以直接导入了。推荐放到site-packages(专门存放模块的文件夹)里
一般模块只导入一次
如果一定要重新加载模块,可使用模块 importlib 中的函数 reload ,它接受一个参数(要
重新加载的模块),并返回重新加载的模块。如果在程序运行时修改了模块,并希望这种修改反映到程序中,这将很有用。
>>> import importlib
>>> hello = importlib.reload(hello)
Hello, world!
2,模块是用来下定义的
1.2.1在模块中定义函数
1.2.2.在模块中添加测试代码
# hello3.py
def hello():
print("Hello, world!")
# 一个测试:
hello()
但其实导入模块就会执行程序中的代码,测试代码会在导入时自动运行。为避免这种情况,可使用变量 __name__判断当前是作为程序运行(测试)还是导入的模块。
>>> import hello3
Hello, world!
>>> hello3.hello()
Hello, world!
>>> __name__
'__main__'
>>> hello3.__name__
'hello3
改进后
# hello4.py
def hello():
print("Hello, world!")
def test():
hello()
if __name__ == '__main__': test()
3,包
其实就是另一种模块,只不过这个模块包含其他模块。
模块存储在扩展名为.py的文件中,而包则是一个目录。要被Python视为包,目录必须包含文件__init__.py。如果像普通模块一样导入包,文件__init__.py的内容就将是包的内容。
还可以嵌套其他包.
二,探索模块
2.1. 使用 dir
要查明模块包含哪些东西,可使用函数 dir ,它列出对象的所有属性(对于模块,它列出所有的函数、类、变量等)
2.2.变量__all__
这个变量包含一个列表,它与前面使用列表推导创建的列表类似,但是在模块内部设置的。提供公有接口,是from module import *导入的内容。
它是在模块内部直接设立的
2.3.使用help获取帮助,是从文档字符串中提取的,但比文档字符串包含更多内容。
2.4.__doc__
2.5.__file__
三,一些常用模块
3.1.sys
3.2.os
3.3.fileinput
3.4.集合、堆和双端队列
3.4.1集合
#集合
t=set(range(10))
print(t)
print("type({}) = ",type({}))#这是空字典
a={1,3,2,5,6}
b={0,2,4,5,7}
print("a = ",a)
print("b = ",b)
#add
a.add(9)
print("a ofter add = ",a)
#remove
a.remove(9)
print("a ofter remove = ",a)
#取并集
print("a.union(b) = ",a.union(b))
print("a|b = ",a|b)
#取交集
print("a.intersection(b) = ",a.intersection(b))
print("a&b = ",a&b)
#判断子集
c = a & b
print("c.issubset(a) = ",c.issubset(a))
#判断超集
print("a.issuperset© = ",a.issuperset©)
#判断不同
print("a.symmetric_difference(b) = ",a.symmetric_difference(b))
print("a ^ b = ",a ^ b)
#a与b不同
print("a - b = ",a - b)
print("a.difference(b) = ",a.difference(b))
#b与a不同
print("b - a = ",b - a)
print("b.difference(a) = ",b.difference(a))
print("c <= a = ",c <= a)
print("c >= a = ",c >= a)
print("a.copy() = ",a.copy())
print("a.copy() is a = ",a.copy() is a)
#集合的元素必须不可变
#集合的集合: frozenset 类型,它表示不可变(可散列)的集合
#构造函数 frozenset 创建给定集合的副本
a.add(frozenset(b))
print("a (after a.add(frozenset(b))) = ",a)
my_sets = []
for i in range(10):
my_sets.append(set(range(i, i+5)))
print("my_sets = ",my_sets)
#reduce(set.union, my_sets)
#reduce?
3.4.2堆
#堆heap
#它是一种优先队列.优先队列让你能够以任意顺序添加对象
#并随时(可能是在两次添加对象之间)找出(并删除)最小的元素
#相比于列表方法min,这样做的效率要高得多
#heappush 用于在堆中添加一个元素
#不能将它用于普通列表,而只能用于使用各种堆函数创建的列表
from heapq import *
from random import shuffle
data = list(range(10))
shuffle(data)
heap =[]
for n in data:
heappush(heap,n)
print("heap = ",heap)
heappush(heap,0.5)
print("heap = ",heap)
#heappop 弹出最小的元素(总是位于索引0处)
#并确保剩余元素中最小的那个位于索引0处(保持堆特征)
for i in range(3):
print(“heappop(heap)”,heappop(heap))
print("heap = ",heap)
#heapify通过执行尽可能少的移位操作将列表变成合法的堆(即具备堆特征)
heap=[5, 8, 0, 3, 6, 7, 9, 1, 4, 2]
heapify(heap)
print("heap = ",heap)
#函数 heapreplace 用得没有其他函数那么多
#它从堆中弹出最小的元素,再压入一个新元素
#相比于依次执行函数 heappop 和 heappush ,这个函数的效率更高
heapreplace(heap,0.5)
print("heap after heapreplace(heap,0.5)= ",heap)
#模块 heapq 中还有两个函数没有介绍:
#nlargest(n, iter) 和 nsmallest(n, iter)
#分别用于找出可迭代对象 iter 中最大和最小的 n 个元素
#这种任务也可通过先排序(如使用函数sorted )再切片来完成
#但堆算法的速度更快,使用的内存更少(而且使用起来也更容易)
3.4.3双端队列
#双端队列deque 在模块 collections 中
#与集合(set)一样,双端队列也是从可迭代对象创建的
from collections import deque
q = deque(range(5))
q.append(5)
q.appendleft(6)
print(“q =”,q)
print(“q.pop() =”,q.pop())
print(“q.popleft() =”,q.popleft())
q.rotate(3)#右移
print("q = ", q)
q.rotate(-1)#左移print("q = ",q)
3.5.time
#time
import time
#asctime将时间元组转换为字符串
print("time.asctime() = ",time.asctime())#asctime()不提供参数返回当前时间
#time.localtime将一个实数(从新纪元开始后的秒数)转换为日期元组(本地时间)
print("time.localtime(time.time()) = ", time.localtime(time.time()) )
#time.mktime 将日期元组转换为从新纪元后的秒数
#time.sleep 让解释器等待指定的秒数
#time.strptime 将一个字符串(其格式与 asctime 所返回字符串的格式相同)
#转换为日期元组.(可选参数format遵循的规则与strftime相同,详情请参阅标准文档
#time.time 返回当前的国际标准时间,以从新纪元开始的秒数表示
#还有两个较新的与时间相关的模块: datetime 和 timeit.
#前者提供了日期和时间算术支持,而后者可帮助你计算代码段的执行时间。
#"Python库参考手册"提供了有关这两个模块的详细信息
3.6.random
#random模块 random 包含生成伪随机数的函数
#如果你要求真正的随机(如用于加密或实现与安全相关的功能)
#应考虑使用模块 os 中的函数 urandom
#random() 返回一个0~1(含)的随机实数
#getrandbits(n) 以长整数方式返回 n 个随机的二进制位
#uniform(a, b) 返回一个 a ~ b (含)的随机实数
#randrange([start], stop, [step]) 从 range(start, stop, step) 中随机地选择一个数
#choice(seq) 从序列 seq 中随机地选择一个元素
#shuffle(seq[, random]) 就地打乱序列 seq
#sample(seq, n) 从序列 seq 中随机地选择 n 个值不同的元素#
#P192
3.7.shelve 和 json
3.7.1 .shelve
import shelve
s=shelve.open(‘test.dat’)
s[‘x’]=[‘a’,‘b’,‘c’]
s[‘x’].append(‘d’)#注意,shelve.open返回的并非普通的映射
#这个操作并没用
print("s[‘x’] = ",s[‘x’])
#解决:
temp=s[‘x’]
temp.append(‘d’)
s[‘x’]=temp
print("s[‘x’] = ",s[‘x’])
#解决2:将函数 open 的参数 writeback 设置为 True
#database.py