Python基础任务5

File

open() 方法

Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。

注意:使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。

open() 函数常用形式是接收两个参数:文件名(file)模式(mode)

1
>>> open(file, mode='r')

完整的语法格式为:

1
>>> open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

参数说明:

  • file:必需,文件路径(相对或者绝对路径)。
  • mode:可选,文件打开模式
  • buffering:设置缓冲
  • encoding:一般使用utf8
  • errors:报错级别
  • newline:区分换行符
  • closefd:传入的file参数类型
  • opener:

mode 参数有:

模式 描述
t 文本模式 (默认)。默认为文本模式
x 写模式,新建一个文件,如果该文件已存在则会报错。
b 二进制模式。
+ 打开一个文件进行更新(可读可写)。
U 通用换行模式(不推荐)。
r 只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。
w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在创建新文件
wb 二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在创建新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

文件对象的操作方法

file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数:

方法 描述
file.close() 关闭文件。关闭后文件不能再进行读写操作。
file.flush() 刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。
file.next() 返回文件下一行
file.read([size]) 从文件读取指定的字节数,如果未给定或为负则读取所有。
file.readline([size]) 读取整行,包括 “\n” 字符。
file.readlines([sizeint]) 读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区。
file.tell() 返回文件当前位置
file.write(str) 将字符串写入文件返回的是写入的字符长度
file.writelines(sequence) 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符

OS模块

os 模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示:

方法 描述
os.chdir(path) 改变当前工作目录
os.getcwd() 返回当前工作目录
os.getcwdu() 返回一个当前工作目录的Unicode对象
os.listdir(path) 返回path指定的文件夹包含的文件或文件夹的名字的列表。
os.makedirs(path[, mode]) 递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。
os.mkdir(path[, mode]) 以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。
os.readlink(path) 返回软链接所指向的文件
os.remove(path) 删除路径为path的文件。如果path是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。
os.removedirs(path) 递归删除目录。
os.rename(src, dst) 重命名文件或目录,从 src 到 dst
os.renames(old, new) 递归地对目录进行更名,也可以对文件进行更名。
os.rmdir(path) 删除path指定的空目录,如果目录非空,则抛出一个OSError异常。
os.stat(path) 获取path指定的路径的信息,功能等同于C API中的stat()系统调用。
os.unlink(path) 删除文件路径
os.path 模块 获取文件的属性信息。

datetime模块

datetime是Python处理日期和时间的标准库。

获取当前日期和时间

1
2
3
4
5
>>> from datetime import datetime
>>> print(datetime.now())
2019-04-08 20:43:32.124067
>>> print(type(datetime.now()))
<class 'datetime.datetime'>

注意到datetime是模块,datetime模块还包含一个datetime类,通过from datetime import datetime导入的才是datetime这个类。

如果仅导入import datetime,则必须引用全名datetime.datetime

datetime.now()返回当前日期和时间,其类型是datetime

获取指定日期和时间

要指定某个日期和时间,直接用参数构造一个datetime

1
2
3
>>> from datetime import datetime
>>> print(datetime(2018,8,8,8,8))
2018-08-08 08:08:00

datetime转换为timestamp

在计算机中,时间实际上是用数字表示的。我们把1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch time,记为0(1970年以前的时间timestamp为负数),当前时间就是相对于epoch time的秒数,称为timestamp。

把一个datetime类型转换为timestamp只需要简单调用timestamp()方法:

1
2
3
4
>>> from datetime import datetime
>>> dt = datetime(2018,8,8,8,8)
>>> dt.timestamp()
1533686880.0

注意Python的timestamp是一个浮点数。如果有小数位,小数位表示毫秒数。

timestamp转换为datetime

要把timestamp转换为datetime,使用datetime提供的fromtimestamp()方法:

1
2
3
4
>>> from datetime import datetime
>>> t = 1533686880.0
>>> print(datetime.fromtimestamp(t))
2018-08-08 08:08:00

注意到timestamp是一个浮点数,它没有时区的概念,而datetime是有时区的。上述转换是在timestamp和本地时间做转换。

timestamp也可以直接被转换到UTC标准时区的时间:

1
2
3
4
5
6
>>> from datetime import datetime
>>> t = 1533686880.0
>>> print(datetime.fromtimestamp(t)) # 本地时间
2018-08-08 08:08:00
>>> print(datetime.utcfromtimestamp(t)) # UTC时间
2018-08-08 00:08:00

str转换为datetime

很多时候,用户输入的日期和时间是字符串,要处理日期和时间,首先必须把str转换为datetime。转换方法是通过datetime.strptime()实现,需要一个日期和时间的格式化字符串:

1
2
3
4
>>> from datetime import datetime
>>> day = datetime.strptime('2018-8-8 08:08:00','%Y-%m-%d %H:%M:%S')
>>> print(day)
2018-08-08 08:08:00

字符串'%Y-%m-%d %H:%M:%S'规定了日期和时间部分的格式。注意转换后的datetime是没有时区信息的。

datetime转换为str

如果已经有了datetime对象,要把它格式化为字符串显示给用户,就需要转换为str,转换方法是通过strftime()实现的,同样需要一个日期和时间的格式化字符串:

1
2
3
>>> from datetime import datetime
>>> print(datetime.now().strftime('%a, %b %d %H:%M'))
Mon, Apr 08 21:23

datetime表示的时间需要时区信息才能确定一个特定的时间,否则只能视为本地时间。

如果要存储datetime,最佳方法是将其转换为timestamp再存储,因为timestamp的值与时区完全无关。

类和对象

类定义

语法格式如下:

1
2
3
4
5
6
>>> class ClassName:
<statement-1>
.
.
.
<statement-N>

类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。

类对象

类对象支持两种操作:属性引用实例化

属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name

类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用,像下面这样:

1
2
>>> def __init__(self):
self.data = []

类定义了 __init__() 方法,类的实例化操作会自动调用 __init__() 方法。

__init__() 方法可以有参数,参数通过__init__() 传递到类的实例化操作上。

1
2
3
4
5
6
>>> class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
>>> x = Complex(3.0, -4.5)
>>> print(x.r, x.i) # 输出结果:3.0 -4.5

self代表类的实例,而非类。

正则表达式

模式字符串使用特殊的语法来表示一个正则表达式:

字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

多数字母和数字前加一个反斜杠时会拥有不同的含义。

标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

反斜杠本身需要使用反斜杠转义。

由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\t',等价于 \\t )匹配相应的特殊字符。

下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

模式 描述
^ 匹配字符串的开头
$ 匹配字符串的末尾。
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[…] 用来表示一组字符,单独列出:[amk] 匹配 ‘a’,’m’或’k’
... 不在[]中的字符:abc 匹配除了a,b,c之外的字符。
re* 匹配0个或多个的表达式。
re+ 匹配1个或多个的表达式。
re? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n,} 精确匹配n个前面表达式。例如,”o{2,}”不能匹配”Bob”中的”o”,但能匹配”foooood”中的所有o。”o{1,}”等价于”o+”。”o{0,}”则等价于”o*”。
re{ n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a \ b 匹配a或b
(re) 匹配括号内的表达式,也表示一个组
(?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re) 类似 (…), 但是不表示一个组
(?imx: re) 在括号中使用i, m, 或 x 可选标志
(?-imx: re) 在括号中不使用i, m, 或 x 可选标志
(?#…) 注释.
(?= re) 前向肯定界定符。如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re) 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。
(?> re) 匹配的独立模式,省去回溯。
\w 匹配数字字母下划线
\W 匹配非数字字母下划线
\s 匹配任意空白字符,等价于 [\t\n\r\f]。
\S 匹配任意非空字符
\d 匹配任意数字,等价于 [0-9]。
\D 匹配任意非数字
\Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z 匹配字符串结束
\G 匹配最后匹配完成的位置。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B 匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
\n, \t, 等。 匹配一个换行符。匹配一个制表符, 等
\1…\9 匹配第n个分组的内容。
\10 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式

re模块

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。

re 模块使 Python 语言拥有全部的正则表达式功能。

re.match函数

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none

1
>>> re.match(pattern, string, flags=0)

参数说明:

  • pattern:匹配的正则表达式
  • string:要匹配的字符串。
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

匹配成功re.match方法返回一个匹配的对象,否则返回None

re.search方法

re.search 扫描整个字符串并返回第一个成功的匹配

1
>>> re.search(pattern, string, flags=0)

参数说明:

  • pattern:匹配的正则表达式
  • string:要匹配的字符串。
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

匹配成功re.search方法返回一个匹配的对象,否则返回None

检索和替换

Python 的re模块提供了re.sub用于替换字符串中的匹配项。

1
>>> re.sub(pattern, repl, string, count=0)

参数说明:

  • pattern:正则中的模式字符串。
  • repl:替换的字符串,也可为一个函数。
  • string:要被查找替换的原始字符串。
  • count:模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
1
2
3
4
5
6
7
8
9
10
11
>>> import re
>>> phone = "2004-959-559 # 这是一个电话号码"

>>> # 删除注释
>>> num = re.sub(r'#.*$', "", phone)
>>> print ("电话号码 : ", num)
电话号码 : 2004-959-559
>>> # 移除非数字的内容
>>> num = re.sub(r'\D', "", phone)
>>> print ("电话号码 : ", num)
电话号码 : 2004959559

repl 参数可以是一个函数

compile 函数

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。

1
>>> re.compile(pattern[, flags])

参数:

  • pattern:一个字符串形式的正则表达式
  • flags:可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
    • re.I:忽略大小写
    • re.L:表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
    • re.M:多行模式
    • re.S:即为’ . ‘并且包括换行符在内的任意字符(’ . ‘不包括换行符)
    • re.U:表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
    • re.X:为了增加可读性,忽略空格和’ # ‘后面的注释

findall

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

注意: match 和 search 是匹配一次,findall 匹配所有。

1
>>> findall(string[, pos[, endpos]])

参数:

  • string:待匹配的字符串。
  • pos:可选参数,指定字符串的起始位置,默认为 0。
  • endpos:可选参数,指定字符串的结束位置,默认为字符串的长度。

re.finditer

findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

1
>>> re.finditer(pattern, string, flags=0)

参数:

  • pattern:匹配的正则表达式
  • string:要匹配的字符串。
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

re.split

split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

1
>>> re.split(pattern, string[, maxsplit=0, flags=0])

参数:

  • pattern:匹配的正则表达式
  • string:要匹配的字符串。
  • maxsplit:分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

http请求

python 3.x 以上版本揽括了 urllib2,把urllib2 和 urllib 整合到一起。
Python实现HTTP请求有以下两种方式:

urllib

1
2
3
4
5
6
7
>>> import urllib
>>> response = urllib.request.urlopen('https://skyelan.github.io/')
>>> print(response.read())

>>> req = urllib.request.Request(url='https://skyelan.github.io/', data=b'This data is passed to stdin of the CGI')
>>> f = urllib.request.urlopen(req)
>>> print(f.read().decode('utf-8'))

Requests

1
2
3
4
5
6
7
8
9
10
11
>>> #get请求
>>> import requests
>>> url = 'https://skyelan.github.io/'
>>> requests = requests.get(url)
>>> print(requests.content)

>>> #post请求
>>> url = 'https://skyelan.github.io/'
>>> postdata = {'key': 'value'}
>>> requests = requests.post(url, data=postdata)
>>> print(requests.content)
-------------本文结束感谢您的阅读-------------
您的支持将是我前进的动力!