模块
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)
最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块
不能和Python自带的模块名称冲突
一个
abc.py
的文件就是一个名字叫abc
的模块,一个xyz.py
的文件就是一个名字叫xyz
的模块
包Package
为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)
- 每一个包目录下面都会有一个
__init__.py
的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py
可以是空文件,也可以有Python代码,因为__init__.py
本身就是一个模块,而它的模块名就是mycompany
。
- 每一个包目录下面都会有一个
使用模块
导入模块:
import module
从包导入模块:
form package import module
常见内置模块
datetime
datetime是Python处理日期和时间的标准库
获取当前时间datetime.now()
>>> from datetime import datetime #datetime是模块,datetime模块还包含一个datetime类,通过from datetime import datetime导入的才是datetime这个类
>>> now = datetime.now() # 获取当前datetime
>>> print(now)
2015-05-18 16:28:07.198690
>>> print(type(now))
<class 'datetime.datetime'>
获取指定日期和时间datetime(年,月,日,时,分,秒)
>> from datetime import datetime
>>> dt = datetime(2015, 4, 19, 12, 20) # 用指定日期时间创建datetime
>>> print(dt)
2015-04-19 12:20:00
datetime转timestamp
计算机中,时间实际上是用数字表示的。我们把1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch time,记为
0
(1970年以前的时间timestamp为负数),当前时间就是相对于epoch time的秒数,称为timestamp。timestamp的值与时区毫无关系,因为timestamp一旦确定,其UTC时间就确定了,转换到任意时区的时间也是完全确定的
Python的timestamp是一个浮点数。如果有小数位,小数位表示毫秒数
>>> from datetime import datetime
>>> dt = datetime(2015, 4, 19, 12, 20) # 用指定日期时间创建datetime
>>> dt.timestamp() # 把datetime转换为timestamp
1429417200.0
timestamp转换为datetime
timestamp是一个浮点数,它没有时区的概念,而datetime是有时区的。如果不传入时区timestamp和本地时间做转换
>>> from datetime import datetime
>>> t = 1429417200.0
>>> print(datetime.fromtimestamp(t)) # 本地时间
2015-04-19 12:20:00
>>> print(datetime.utcfromtimestamp(t)) # UTC时间
2015-04-19 04:20:00
str转换为datetime
很多时候,用户输入的日期和时间是字符串,要处理日期和时间,首先必须把str转换为datetime。转换方法是通过
datetime.strptime()
实现,需要一个日期和时间的格式化字符串转换后的datetime是没有时区信息的
>>> from datetime import datetime
>>> cday = datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S')
>>> print(cday)
2015-06-01 18:19:59
datetime转换为str
- 如果已经有了datetime对象,要把它格式化为字符串显示给用户,就需要转换为str,转换方法是通过
strftime()
实现的
- 如果已经有了datetime对象,要把它格式化为字符串显示给用户,就需要转换为str,转换方法是通过
>>> from datetime import datetime
>>> now = datetime.now()
>>> print(now.strftime('%a, %b %d %H:%M'))
Mon, May 05 16:28
datetime加减
- 对日期和时间进行加减实际上就是把datetime往后或往前计算,得到新的datetime。加减可以直接用
+
和-
运算符,不过需要导入timedelta
这个类:
- 对日期和时间进行加减实际上就是把datetime往后或往前计算,得到新的datetime。加减可以直接用
>>> from datetime import datetime, timedelta
>>> now = datetime.now()
>>> now
datetime.datetime(2015, 5, 18, 16, 57, 3, 540997)
>>> now + timedelta(hours=10)
datetime.datetime(2015, 5, 19, 2, 57, 3, 540997)
>>> now - timedelta(days=1)
datetime.datetime(2015, 5, 17, 16, 57, 3, 540997)
>>> now + timedelta(days=2, hours=12)
datetime.datetime(2015, 5, 21, 4, 57, 3, 540997)
本地时间转换为UTC时间
- 如果系统时区恰好是UTC+8:00,那么下述代码就是正确的,否则,不能强制设置为UTC+8:00时区。
>>> from datetime import datetime, timedelta, timezone
>>> tz_utc_8 = timezone(timedelta(hours=8)) # 创建时区UTC+8:00
>>> now = datetime.now()
>>> now
datetime.datetime(2015, 5, 18, 17, 2, 10, 871012)
>>> dt = now.replace(tzinfo=tz_utc_8) # 强制设置为UTC+8:00
>>> dt
datetime.datetime(2015, 5, 18, 17, 2, 10, 871012, tzinfo=datetime.timezone(datetime.timedelta(0, 28800)))
时区转换
通过
utcnow()
拿到当前的UTC时间,再转换为任意时区的时间:转换的关键在于,拿到一个
datetime
时,要获知其正确的时区,然后强制设置时区,作为基准时间。用带时区的datetime
,通过astimezone()
方法,可以转换到任意时区。
# 拿到UTC时间,并强制设置时区为UTC+0:00:
>>> utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc)
>>> print(utc_dt)
2015-05-18 09:05:12.377316+00:00
# astimezone()将转换时区为北京时间:
>>> bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8)))
>>> print(bj_dt)
2015-05-18 17:05:12.377316+08:00
# astimezone()将转换时区为东京时间:
>>> tokyo_dt = utc_dt.astimezone(timezone(timedelta(hours=9)))
>>> print(tokyo_dt)
2015-05-18 18:05:12.377316+09:00
# astimezone()将bj_dt转换时区为东京时间:
>>> tokyo_dt2 = bj_dt.astimezone(timezone(timedelta(hours=9)))
>>> print(tokyo_dt2)
2015-05-18 18:05:12.377316+09:00
collection
collections是Python内建的一个集合模块,提供了许多有用的集合类。
namedtuple
namedtuple
是一个函数,它用来创建一个自定义的tuple
对象,并且规定了tuple
元素的个数,并可以用属性而不是索引来引用tuple
的某个元素>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x
1
>>> p.y
2
deque
使用
list
存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list
是线性存储,数据量大的时候,插入和删除效率很低。deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
deque
除了实现list的append()
和pop()
外,还支持appendleft()
和popleft()
,这样就可以非常高效地往头部添加或删除元素。>>> from collections import deque
>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])
defaultdict
使用
dict
时,如果引用的Key不存在,就会抛出KeyError
。如果希望key不存在时,返回一个默认值,就可以用defaultdict
:默认值是调用函数返回的,而函数在创建
defaultdict
对象时传入。除了在Key不存在时返回默认值,
defaultdict
的其他行为跟dict
是完全一样的。>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默认值
'N/A'
OrderedDict
使用
dict
时,Key是无序的。在对dict
做迭代时,我们无法确定Key的顺序。 如果要保持Key的顺序,可以用OrderedDict
:OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序OrderedDict
可以实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最早添加的Key:>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是无序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
ChainMap
ChainMap
可以把一组dict
串起来并组成一个逻辑上的dict
。ChainMap
本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找。
- 什么时候使用
ChainMap
最合适?举个例子:应用程序往往都需要传入参数,参数可以通过命令行传入,可以通过环境变量传入,还可以有默认参数。我们可以用ChainMap
实现参数的优先级查找,即先查命令行参数,如果没有传入,再查环境变量,如果没有,就使用默认参数。 ```python from collections import ChainMap import os, argparse
构造缺省参数:
defaults = { ‘color’: ‘red’, ‘user’: ‘guest’ }
构造命令行参数:
parser = argparse.ArgumentParser() parser.add_argument(‘-u’, ‘—user’) parser.add_argument(‘-c’, ‘—color’) namespace = parser.parse_args() command_line_args = { k: v for k, v in vars(namespace).items() if v }
组合成ChainMap:
combined = ChainMap(command_line_args, os.environ, defaults)
打印参数:
print(‘color=%s’ % combined[‘color’]) print(‘user=%s’ % combined[‘user’])
<a name="sdmibb"></a>
#### Counter
- `Counter`是一个简单的计数器,例如,统计字符出现的个数:
```python
>>> from collections import Counter
>>> c = Counter()
>>> for ch in 'programming':
... c[ch] = c[ch] + 1
...
>>> c
Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})
Counter
实际上也是dict
的一个子类
base64
struct
hashlib
hmac
itertools
contextlib
urllib
xml
HTMLParser
第三方模块
除了内建的模块外,Python还有大量的第三方模块。
基本上,所有的第三方模块都会在PyPI - the Python Package Index上注册,只要找到对应的模块名字,即可用pip安装。
安装第三方模块
- pip安装(首先需要安装pip)
pip install Pillow
Anaconda
基于Python的数据处理和科学计算平台,它已经内置了许多非常有用的第三方库,我们装上Anaconda,就相当于把数十个第三方模块自动安装好了,非常简单易用。
可以从Anaconda官网下载GUI安装包,安装包有500~600M,所以需要耐心等待下载。网速慢的同学请移步国内镜像。下载后直接安装,Anaconda会把系统Path中的python指向自己自带的Python,并且,Anaconda安装的第三方模块会安装在Anaconda自己的路径下,不影响系统已安装的Python目录。安装好Anaconda后,重新打开命令行窗口,输入python,可以看到Anaconda的信息
- 安装完成后导入使用模块, 默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在
sys
模块的path
变量中:>>> import sys
>>> sys.path
['', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', ..., '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages']
pillow
PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了
pillow是基于PIL开发的,支持python3,并加入了很多新特性。 https://pillow.readthedocs.org/
安装Pillow:
- 如果安装了Anaconda,Pillow就已经可用了。否则,需要在命令行下通过pip安装:
$ pip install pillow
- 如果安装了Anaconda,Pillow就已经可用了。否则,需要在命令行下通过pip安装:
操作 ```python from PIL import Image
打开一个jpg图像文件,注意是当前路径:
im = Image.open(‘test.jpg’)
获得图像尺寸:
w, h = im.size print(‘Original image size: %sx%s’ % (w, h))
缩放到50%:
im.thumbnail((w//2, h//2)) print(‘Resize image to: %sx%s’ % (w//2, h//2))
把缩放后的图像用jpeg格式保存:
im.save(‘thumbnail.jpg’, ‘jpeg’)
from PIL import Image, ImageFilter
打开一个jpg图像文件,注意是当前路径:
im = Image.open(‘test.jpg’)
应用模糊滤镜:
im2 = im.filter(ImageFilter.BLUR) im2.save(‘blur.jpg’, ‘jpeg’)
- PIL的`ImageDraw`提供了一系列绘图方法,让我们可以直接绘图。比如要生成字母验证码图片:
```python
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
# 随机字母:
def rndChar():
return chr(random.randint(65, 90))
# 随机颜色1:
def rndColor():
return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))
# 随机颜色2:
def rndColor2():
return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))
# 240 x 60:
width = 60 * 4
height = 60
image = Image.new('RGB', (width, height), (255, 255, 255))
# 创建Font对象:
font = ImageFont.truetype('Arial.ttf', 36)
# 创建Draw对象:
draw = ImageDraw.Draw(image)
# 填充每个像素:
for x in range(width):
for y in range(height):
draw.point((x, y), fill=rndColor())
# 输出文字:
for t in range(4):
draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2())
# 模糊:
image = image.filter(ImageFilter.BLUR)
image.save('code.jpg', 'jpeg')
request
用于访问网络资源,比内置的urllib功能更强大
如果安装了Anaconda,requests就已经可用了。否则,需要在命令行下通过pip安装:
$ pip install requests
使用
- 通过GET访问一个页面
>>> import requests
>>> r = requests.get('https://www.douban.com/') # 豆瓣首页
>>> r.status_code
200
>>> r.text
r.text
'<!DOCTYPE HTML>\n<html>\n<head>\n<meta name="description" content="提供图书、电影、音乐唱片的推荐、评论和...'
xlwt xlrd(处理excel)
使用xlwt module将数据写入Excel表格,使用xlrd module从Excel读取数据
xlwt编辑excel
# -*- coding: utf-8 -*-
#导入xlwt模块
import xlwt
# 创建一个Workbook对象,这就相当于创建了一个Excel文件
book = xlwt.Workbook(encoding='utf-8', style_compression=0)
'''
Workbook类初始化时有encoding和style_compression参数
encoding:设置字符编码,一般要这样设置:w = Workbook(encoding='utf-8'),就可以在excel中输出中文了。
默认是ascii。当然要记得在文件头部添加:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
style_compression:表示是否压缩,不常用。
'''
#创建一个sheet对象,一个sheet对象对应Excel文件中的一张表格。
# 在电脑桌面右键新建一个Excel文件,其中就包含sheet1,sheet2,sheet3三张表
sheet = book.add_sheet('test', cell_overwrite_ok=True)
# 其中的test是这张表的名字,cell_overwrite_ok,表示是否可以覆盖单元格,其实是Worksheet实例化的一个参数,默认值是False
# 向表test中添加数据
sheet.write(0, 0, 'EnglishName') # 其中的'0-行, 0-列'指定表中的单元,'EnglishName'是向该单元写入的内容
sheet.write(1, 0, 'Marcovaldo')
txt1 = '中文名字'
sheet.write(0, 1, txt1.decode('utf-8')) # 此处需要将中文字符串解码成unicode码,否则会报错
txt2 = '马可瓦多'
sheet.write(1, 1, txt2.decode('utf-8'))
# 最后,将以上操作保存到指定的Excel文件中
book.save(r'e:\test1.xls') # 在字符串前加r,声明为raw字符串,这样就不会处理其中的转义了。否则,可能会报错
xlrd读取excel
# -*- coding: utf-8 -*-
import xlrd
xlsfile = r"C:\Users\Administrator\Desktop\test\Account.xls"# 打开指定路径中的xls文件
book = xlrd.open_workbook(xlsfile)#得到Excel文件的book对象,实例化对象
sheet0 = book.sheet_by_index(0) # 通过sheet索引获得sheet对象
print "1、",sheet0
sheet_name = book.sheet_names()[0]# 获得指定索引的sheet表名字
print "2、",sheet_name
sheet1 = book.sheet_by_name(sheet_name)# 通过sheet名字来获取,当然如果知道sheet名字就可以直接指定
nrows = sheet0.nrows # 获取行总数
print "3、",nrows
#循环打印每一行的内容
for i in range(nrows):
print sheet1.row_values(i)
ncols = sheet0.ncols #获取列总数
print "4、",ncols
row_data = sheet0.row_values(0) # 获得第1行的数据列表
print row_data
col_data = sheet0.col_values(0) # 获得第1列的数据列表
print "5、",col_data
# 通过坐标读取表格中的数据
cell_value1 = sheet0.cell_value(0, 0)
print "6、",cell_value1
cell_value2 = sheet0.cell_value(0, 1)
print "7、",cell_value2
xlutils
#coding=utf-8
#######################################################
#filename:test_xlutils.py
#author:defias
#date:xxxx-xx-xx
#function:向excel文件中写入数据
#######################################################
import xlrd
import xlutils.copy
#打开一个workbook
rb = xlrd.open_workbook('E:\\Code\\Python\\test1.xls')
wb = xlutils.copy.copy(rb)
#获取sheet对象,通过sheet_by_index()获取的sheet对象没有write()方法
ws = wb.get_sheet(0)
#写入数据
ws.write(1, 1, 'changed!')
#添加sheet页
wb.add_sheet('sheetnnn2',cell_overwrite_ok=True)
#利用保存时同名覆盖达到修改excel文件的目的,注意未被修改的内容保持不变
wb.save('E:\\Code\\Python\\test1.xls')
openpyxl:读、写xlsx
https://blog.csdn.net/weixin_43094965/article/details/82226263
安装:pip install openpyxl
新建
from openpyxl import Workbook
wb = Workbook() #实例化、即创建一个excel对象
ws = wb.active #激活第一个sheet。
ws2 = wb.create_sheet('sheet名称', 0) #新建sheet。 可选参数数字,表示sheet位置, 不写插入最后,0是第一
ws3= wb['表格名称'] #选择sheet,通过sheet名称索引, 也可以ws3=wb.get_sheet_by_name('表格名称')
操作数据
对ws对象进行访问操作。