Python学习个人简记
Python学习 ¶
类型 ¶
类型转换 ¶
int()
:将…转换为整数
float()
:将…转换为浮点数
str()
:将…转换为字符串
判断类型 ¶
查看变量类型type()
,传入变量会告诉类型
判断变量类型isinstance(elem, type)
:判断elem是否为type类型,返回bool类型的真假
字符串 ¶
原始字符串:字符串前加一个r
,可以不用转义
方法/函数 | 参数 | 返回值 | 作用 |
---|---|---|---|
.title() | 新字符串 | 将字符串各单词首字母改为大写 | |
.upper() | 新字符串 | 将字符串中字母全部改为大写 | |
.lower() | 新字符串 | 将字符串中字母全部改为小写 | |
.rstrip() | 新字符串 | 将字符串右侧空白删除 | |
.lstrip() | 新字符串 | 将字符串左侧空白删除 | |
.strip() | 新字符串 | 将字符串两端空白删除 | |
str() | 1 | 新字符串 | 将参数类型转换为字符串 |
.replace(old,new) | 将字符串中old替换成new字符串 | ||
.split(sep=None) | 分隔符 | 拆分后的列表 | 用参数作为分隔符拆分字符串返回列表 |
.join(iterable) | 序列 | 字符串 | 将参数序列用.前的字符作为分隔符拼起来 |
格式化 ¶
format格式化 ¶
1 | # 位置参数 |
%格式化操作符 ¶
1 | "%c" % 97 |
序列 ¶
列表 ¶
方法/函数 | 参数 | 返回值 | 作用 |
---|---|---|---|
list() | 可迭代对象 | 列表 | 将可迭代对象转换为列表 |
len() | 列表 | 列表长度 | 返回列表长度 |
max() | 列表 | 一个列表元素 | 返回列表中最大值 |
min() | 列表 | 一个列表元素 | 返回列表中最小值 |
.append() | 1 | 将参数添加到列表末尾 | |
.insert() | 1,2 | 将参数2插入到列表下标为参数1的位置 | |
del | 1(删除索引或切片) | 删除列表元素,用法del alist[1] |
|
.pop() | [1] | 删除的元素 | 删除末尾元素,或下标为参数1的元素 |
.remove() | 1 | 删除列表中第一个值为参数1的元素 | |
.sort() | [reverse=True] | 将原列表从小到大排序(+可选参数从大到小) | |
sorted() | 1,[reverse=True] | 排序好的列表 | 将参数1列表 sort排序 |
.reverse() | 反转列表元素排列顺序 | ||
.extend() | 1(一个列表) | 将参数列表添加到列表末尾 | |
+号运算符 | 将两个列表合并 | ||
.count() | 1 | 统计参数在列表中出现的次数 | |
.index() | 1 | 返回参数在列表中第一次出现的索引值 | |
生成列表 ¶
函数range(start,end,step):包含start不包括end,步长为step
生成序列、元组 ¶
enumerate(iterable)
:生成一个二元组,每个二元组分别是可迭代对象的索引号和对应元素
zip(iter1,....)
:由多个可迭代对象生成多元组
收集参数 ¶
形参前加一个*
,可获取任意数量的参数,将参数变为序列。
实参前加一个*
,可将序列解包
使用range()创建数字列表 ¶
1 | numbers = list(range(1,6)) |
1 | squares = [value**2 for value in range(1,11)] |
列表的切片 ¶
列表切片同 range
1 | players = ['charles', 'martina', 'michael', 'florence', 'eli'] |
负数则倒数开始,-1是倒数第一个
列表的复制 ¶
使用切片来复制列表,不要直接用=
因为只是给原来的列表起了两个名字
元组 ¶
元组是不能被修改的列表
修改元组只能给元组变量重新赋值
元组的定义是看,
逗号,而不是小括号
删除整个元组使用del
tuple(ierable) :将可迭代对象转换为元组
集合 ¶
集合 具有唯一性, 会自动删除重复的数据
创建集合 ¶
1 | set1 = {1,2,3,1} |
使用add()添加元素,remove()移除元素
不可变集合 ¶
1 | set3 = frozenset([1,2,3,1]) |
if ¶
连环判断else if可以写成elif
python的and
对应&&
;or
对应||
确定列表是否为空if alist: #不为空则进入if
三元运算符 ¶
a = x if x<y else y
如果if后条件为true,则为x;否则为y
循环 ¶
for循环 ¶
1 | range(stop) |
while 循环 ¶
else可用于for或者while,表示循环条件不成立时候应执行的内容
当循环有break和else时,break跳出时候并不会执行else内容
字典 ¶
字典示例
1 | alien_0 = {'color': 'green', 'points': 5} |
访问字典
1 | print(alien_0['color']) |
添加键值对
1 | # 直接添加 |
创建空字典
1 | alien_0 = {} |
修改键值
1 | # 直接赋值修改 |
删除键值
1 | # 同列表 |
遍历字典 ¶
遍历所有的键值对 ¶
1 | user_0 = { |
遍历所有键 ¶
1 | for name in favorite_languages.keys(): |
遍历所有值 ¶
1 | for name in favorite_languages.values(): |
字典内置方法 ¶
.fromkeys()
- 用于创建并返回一个新的字典
- 第一个参数是字典的键序列
- 第二个参数是键的值
- 会将所有键初始化为一个值
.get()
- 用于访问字典项
- 第一个参数为 需要查找值的 键
- 第二个参数可选,如果没有找到返回的字符串
.clear()
:用于清空字典.copy()
:拷贝整个字典.pop(key)
:弹出(删除)键.popitem()
:弹出一个键值.setdefault()
:类似于get查找,但如果查找不到键时候会自动添加进字典.update()
:更新字典,例如p.update(name = "LiHua")
当形参收集参数是 两个星号**
时,参数会被打包成字典
函数 ¶
想在函数内修改全局变量,需要使用global
关键字
1 | count = 0 |
想在内部函数修改外部函数的局部变量,使用nonlocal
关键字,用法同global
lambda函数 ¶
1 | lambda x,y:x+y |
filter() 过滤器 ¶
两个参数
-
第一个参数:为函数,则将第二个参数可迭代对象传进去,筛选出函数返回True的值
为None(不可省略),则将第二个参数中 为True的 筛选出来
可结合lambda表达式
1 | list(filter(lambda x:x%2,range(10))) |
map() ¶
map将第二个参数可迭代对象送到第一个参数函数内加工,返回加工后的返回值序列
第二个参数是收集参数,因此第一个参数 函数可以是多参数函数
1 | list(map(lambda x:2*x,range(10))) |
文件系统 ¶
打开文件 ¶
1 | f = open("read.txt") # 以默认只读模式打开 |
mode模式
模式 | 描述 |
---|---|
t | 文本模式 (默认)。 |
x | 写模式,新建一个文件,如果该文件已存在则会报错。 |
b | 二进制模式。 |
+ | 打开一个文件进行更新(可读可写)。 |
U | 通用换行模式(Python 3 不支持)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | **打开一个文件用于追加。**如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
默认为文本模式,如果要以二进制模式打开,加上 b 。
file 对象 ¶
file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数:
序号 | 方法及描述 |
---|---|
1 | file.close()关闭文件。关闭后文件不能再进行读写操作。 |
2 | file.flush()刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。 |
3 | file.fileno()返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。 |
4 | file.isatty()如果文件连接到一个终端设备返回 True,否则返回 False。 |
5 | file.next()**Python 3 中的 File 对象不支持 next() 方法。**返回文件下一行。 |
6 | file.read([size]) 从文件读取指定的字节数,如果未给定或为负则读取所有。 |
7 | file.readline([size]) 读取整行,包括 “\n” 字符。 |
8 | file.readlines([sizeint]) 读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区。 |
9 | file.seek(offset[, whence]) 移动文件读取指针到指定位置 |
10 | file.tell()返回文件当前位置。 |
11 | file.truncate([size]) 从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,其中 windows 系统下的换行代表2个字符大小。 |
12 | file.write(str)将字符串写入文件,返回的是写入的字符长度。 |
13 | file.writelines(sequence)向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。 |
.tell()
:当前文件指针的位置
OS模块 ¶
pickle 保存数据 ¶
pickling:将python的对象转换为二进制数据保存;unpickling:从二进制文件中读取python对象
1 | import pickle |
异常处理 ¶
捕获异常 ¶
1 | try: |
抛出异常 ¶
使用raise
关键字抛出异常
1 | raise ZeroDivisionError("除数不嫩那个为零!") # 括号为对异常的解释,可省略 |
else ¶
只要try语句块没有出现任何异常,就会执行else语句块的内容
with语句 ¶
1 | try: |
类和对象 ¶
定义一个类 ¶
__init__
为构造方法,定义这个类的属性,第一个参数为self(类似this)
1 | class Ball: |
公有、私有 ¶
python默认公有,定义私有属性需要在 变量名或者函数名前加上__
两个下划线,就会变成私有的了。
类的继承 ¶
1 | # 语法 |
子类定义与父类同名的方法或者属性,则会自动覆盖父类对应的方法或者属性(方法重写)
子类在构造方法中需要写父类的构造方法
1 | class Shark(Fish): |
类的组合 ¶
一个类中的属性是另一个类
类对象和实例对象 ¶
1 | class C: |
当对实例对象c的属性进行赋值时,会覆盖类对象的属性;如果没有赋值,则引用类对象的属性
绑定 ¶
类方法第一个参数要传self
类和对象 BIF(内置函数): ¶
BIF | 用途 |
---|---|
issubclass(class,classinfo) |
如果class是classinfo的子类则返回True |
isinstance(object,classinfo) |
如果object是classinfo的[子类]实例对象 返回True |
hasattr(object, name) |
若object对象含有name属性,返回True |
getattr(object, name[,default]) |
返回对象指定的属性值,若属性不存在返回default的值/default不存在AttributeError异常 |
setattr(object,name,value) |
设置对象中指定属性的值,指定属性不存在则新建属性 |
delattr(object,name) |
删除对象指定属性,属性不存在抛出AttributeError异常 |
property() | 给属性绑定getter setter方法 |
classinfo可以为 类对象组成的元组, 只要其中有一个类来符合条件 就可
魔法方法 ¶
注意 ¶
- 魔法方法总是被左右各两个下画线包围,例如_ _init_ _()
- 魔法方法是面向对象的Python的一切
构造和析构 ¶
__init__(self[,…]) ¶
-
相当于构造方法
-
_ _init_ _()
方法的返回值一定是None -
只有在需要进行初始化的时候才重写
-
_ _init_ _()
并不是实例化对象时第一个被调用的魔法方法
__new__(cls[, …]) ¶
- 在一个对象实例化的时候调用的第一个方法
- 第一个参数不是self而是这个类(cls),而其他的参数会直接传递给_ _init_ _()方法
- 返回一个实例对象,通常是cls这个类实例化的对象,当然也可以返回其他对象
- 当继承一个不可变的类型的时候,需要重写这个方法
__del__ ¶
- 只要在程序没有退出的时候,就执行了
del 对象名
,就会执行对象对应的类中的del方法 _ _del_ _()
方法是当垃圾回收机制回收这个对象的时候调用的
算数运算 ¶
- python2.2后将int()、float()、str()、list()、tuple()这些BIF转换为工厂函数
<class 'type'>
- 普通bif是
<class 'builtin_function_or_method'>
- 普通bif是
- 工厂函数理解,工厂函数
常见算术运算 ¶
反运算 ¶
- 反运算魔法方法,一定要注意顺序问题
一元操作符 ¶
定制 ¶
- 如果类中的方法名和属性同名,属性会覆盖方法
属性访问 ¶
-
通过点(.)操作符去访问对象的属性
- 还有bif:getattr,setattr,delattr
- property()函数
-
用
super().
可以有效解决死循环
描述符(property原理) ¶
-
描述符就是将某种特殊类型的类的实例指派给另一个类的属性
- 特殊类型的类指的是:至少要在这个类里边定义
_ _get_ _()
、__set_ _()
或__delete_ _()
三个特殊方法中的任意一个
- 特殊类型的类指的是:至少要在这个类里边定义
-
与其类似的property()
定制序列 ¶
-
容器包括:
- 序列类型:如列表、元组、字符串
- 映射类型:如字典
-
定制容器的有关协议:
- 如果希望定制的容器不可变,则只需要定义
_ _len_ _()
和_ _getitem_ _()
方法 - 如果希望定制的容器是可变的,除了
_ _len_ _()
和_ _getitem_ _()
方法,还需要定义_ _setitem_ _()
和_ _delitem_ _()
两个方法
- 如果希望定制的容器不可变,则只需要定义
-
定制容器相关的魔法方法:
迭代器 ¶
-
提供迭代方法的容器称为迭代器,通常接触的迭代器有序列(如列表、元组、字符)、字典等,它们都支持迭代的操作
-
对一个容器对象调用iter()就得到它的迭代器。调用next()迭代器就会返回下一个值,如果迭代器没有值可以返回了Python会抛出一个名为StopIteration的异常。
生成器 ¶
-
仅通过普通函数,不涉及魔法方法
-
Python是通过生成器来实现类似于协同程序的概念:生成器可以暂时挂起函数,并保留函数的局部变量等数据,然后再次调用它的时候,从上次暂停的位置继续执行下去。
-
yield语句
1
2
3
4
5
6
7
8
9def myGen():
print("生成器被执行")
yield 1
yield 2
myG = myGen()
>>>next(myG) ### 生成器被执行
### 1
>>>next(myG) ### 2 -
由于Python的for循环会自动调用next()方法和处理StopIteration异常,所以for循环当然也是可以对生成器产生作用
生成器表达式 ¶
-
列表推导式
1
21. [i*i for i in range(10)]
2. [i for i in range(10) if not(i%2) and i%3] -
字典推导式
1
22 == 0 for i in range(10)} {i:i %
{0: True, 1: False, 2: True, 3: False, 4: True, 5: False, 6: True, 7: False,8: True, 9: False} -
集合推导式
1
2for i in [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 7, 7, 8]} {i
{1, 2, 3, 4, 5, 6, 7, 8}
模块 ¶
导入模块 ¶
1 | import modelName |
__name__
属性 ¶
作为程序运行时候,py程序的__name__
属性的值是'__main__'
作为模块被导入时,这个值为模块的名字
1 | # 作为模块被导入的时候不会执行,作为程序的时候会执行 |
爬虫 ¶
urllib模块 ¶
模块函数 | 参数/返回值 | 作用 |
---|---|---|
urllib.request.urlopen() |
参数为url字符串或者request对象,返回类文件对象 | 访问网址 |
爬取的都是以utf-8编码的bytes对象
1 | import urllib.request |
示例:下载图片
1 | # coding=utf-8 |
request库 ¶
-
r.text是服务器响应的内容,会自动根据响应头部的字符编码进行解码。
-
r.content也是相应返回的字节码
-
r.encoding是服务器内容使用的文本编码。
-
r.status_code用于检测响应的状态码,如果返回200,就表示请求成功了;如果返回的是4xx,就表示客户端错误;返回5xx则表示服务器错误响应。我们可以用r.status_code来检测请求是否正确响应。
-
使用代理,需配置get()参数
proxies
-
proxies = { 'http' : address, 'https' : address, }
1
2
3
4
5
- 保存cookie,创建一个session对象, 使用session对象来进行get和post
- ```python
session = requests.Session()
-
Xpath模块 ¶
- 安装
python -m pip install lxml
- 使用时需导入
from lxml import etree
学习语法:菜鸟教程 Xpath教程
- 提取标签内容使用
/text()
- 提取标签属性的属性值使用
/@attrname
部分语法
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
… | 选取当前节点的父节点。 |
@ | 选取属性。 |
[starts-with(@attr,value)] |
筛选出 标签属性值前半部分相同的 |
string(.) |
提取标签里所有的文字 |
示例 ¶
1 | from lxml import etree |
- 如果出现中文乱码,自行查看网页编码进行转码,同上面例子
- 其他例子
/html/head/title
:选择HTML文档中head元素内的title元素。/html/head/title/text()
:选择上面提到的title元素的文本。//td
:选择所有的td元素。//div[@class="mine"]
:选择所有具有class="mine"属性的div元
素。
- xpath 返回的是列表,列表元素是Selector类型的对象
.extract()
可以将Selector对象中data参数存储的字符串提取出来
Python并行化 ¶
简单示例
1 | import multiprocessing # 并行化需要导入的库 |
正则表达式 ¶
re模块 ¶
使用前需要导入模块 import re
方法 | 作用 |
---|---|
re.sarch(正则,字符串) |
从字符串中找正则匹配返回 一个匹配对象 |
re.compile(正则字符串) |
将正则编译成模式对象 |
匹配对象.group() |
获得匹配对象匹配的字符串 |
模式对象.findall() |
包含子组则返回子组组成的列表或者元组 |
正则知识 ¶
字符类 ¶
表示一个字符的范围,可以创建一个字符类。
使用中括号将任何内容包起来就是一个字符类;(大小写敏感,可关闭)含义:匹配这个字符类的任何字符就算匹配
- 可使用
-
小斜杠来表示范围- 匹配小写字母
[a-z]
- 匹配小写字母
- 也可直接输入:
[abcde12345]
:匹配abcde12345中的任何一个字符
重复匹配 ¶
使用大括号这对元字符来实现重复匹配的功能
- 匹配 3 次:
[a-z]{3}
- 匹配3次或者4次或者5次(3到5次):
[a-z]{3,5}
元字符 ¶
-
^
:匹配字符串的开始位置 -
$
:匹配字符串的结束位置 -
\
:- 将普通字符变成特殊(转义)字符;或者将特殊字符变成普通字符
- 反斜杠后加数字1~99,表示引用序号对应的子组所匹配的字符串
- 反斜杠后 0开头或者 三位数字 表示八进制数对应的ASCII字符
-
小括号
()
子组:被 元字符小括号
()
括起来的正则表达式称为一个子组例如:
(you)\1
匹配的是youyou
-
中括号
[]
:生成一个字符类,内部的元字符全都市区了特殊的功能-
:表示范围/
:用于字符串转义:\n
匹配换行符^
:表示取反{}
:表示重复- 重复2次
(you){2}
:匹配youyou
- 重复2~4次
(you){2,4}
:匹配youyou
,youyouyou
,youyouyouyou
*
:相当于{0,}
0次或者无穷多次+
:相当于{1,}
匹配至少1次至无穷多次?
:相当于{0,1}
匹配0次或者1次
- 重复2次
元字符 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,‘n’ 匹配字符 “n”。‘\n’ 匹配一个换行符。序列 ‘\’ 匹配 “” 而 “(” 则匹配 “(”。 |
^ |
\A |
$ |
\Z |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?” 可以匹配 “do” 或 “does” 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。 |
? | 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,‘o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。 |
. | 匹配除换行符(\n、\r)之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用像"(.|\n)"的模式。 |
(pattern) | 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 ‘(’ 或 ‘)’。 |
(?:pattern) | 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。 |
(?=pattern) | 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)“能匹配"Windows2000"中的"Windows”,但不能匹配"Windows3.1"中的"Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如"Windows(?!95|98|NT|2000)“能匹配"Windows3.1"中的"Windows”,但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?<=pattern) | 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,"`(?<=95 |
(?<!pattern) | 反向否定预查,与正向否定预查类似,只是方向相反。例如"`(?<!95 |
x|y | 匹配 x 或 y。例如,‘z|food’ 能匹配 “z” 或 “food”。‘(z|f)ood’ 则匹配 “zood” 或 “food”。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如,[^abc] 可以匹配 “plain” 中的’p’、‘l’、‘i’、‘n’。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,[a-z] 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,[^a-z] 可以匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
\cx | 匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。 |
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^0-9] 。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v] 。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
\w | 匹配字母、数字、下划线。等价于[A-Za-z0-9_] 。 |
\W | 匹配非字母、数字、下划线。等价于 [^A-Za-z0-9_] 。 |
\xn | 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,‘\x41’ 匹配 “A”。‘\x041’ 则等价于 ‘\x04’ & “1”。正则表达式中可以使用 ASCII 编码。 |
\num | 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,‘(.)\1’ 匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。 |
\nm | 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 |
\nml | 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 |
\un | 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。 |
实例 ¶
贪婪 和 非贪婪 ¶
贪婪模式:在 符合的条件下,会尽可能多的去匹配
非贪婪:匹配最少次数
默认为贪婪模式,启用非贪婪模式,在 表示重复的元字符后 加上一个?
实践遇到的问题 ¶
-
字符类中匹配
-
,例如一个字符类匹配abc-
4个字符- 需要将
-
写在最前面,如[-abc]
,不写在最前面均表示范围
- 需要将
-
如何匹配小括号
()
-
若匹配的字面值含有
()
需要将其用中括号括起表示一个字符类例如:想匹配
(
需要写成[(]
-
Scrapy 爬虫框架 ¶
1 | 创建项目:scrapy startproject xxx |
框架流程 ¶
**【1】**创建一个scrpy框架项目 ¶
cmd命令行输入
1 | scrapy startproject [dirname] |
会在当前目录生成一个[dirname]的文件夹
该文件夹目录结构为
- scrapy.cfg:项目的配置文件。
- [dirname]/:项目的大本营。
- [dirname]/items.py:定义项目中需要抓取并需要后期处理的数据。
- [dirname]/middlewares.py:项目中的中间件(自定义扩展下载功能的组件)。
- [dirname]/pipelines.py:用于存放执行后期数据处理的功能,从而使得数据的爬取的处理分开
- [dirname]/settings.py:项目的设置文件,配置Scrapy。可以设置user-agent,爬取时间间隔,设置代理等等
- [dirname]/spiders/:放置爬虫代码的目录。
settings.py ¶
1 | # robots协议 |
pipelines.py ¶
需要在setting内开启管道配置
1 | class xxx(): |
middlewares.py ¶
中间件 使用前需要在settings.py中开启
-
MiddleproSpiderMiddleware(obgect)
爬虫中间件 -
MiddleproDownloaderMiddleware(obgect)
下载中间件-
from_crawler
返回下载中间件实例化对象 -
process_request
用来拦截处理请求-
可以写UA伪装
1
2request.headers['User-Agent'] = '' # 可以封装UA池
request.meta['proxy'] = '' # 使用代理
-
-
process_response
用于拦截处理响应 -
process_exception
用于拦截发生异常请求-
一般写代理ip(可以写到request函数)
1
# 代理池
-
-
spider_opend
打印日志
-
**【2】**定义Items.py ¶
Items是将要装载抓取的数据的容器,它工作方式像python里面的字典,但它提供更多的保护,比如对未定义的字段填充以防止拼写错误。
它通过创建一个scrapy.item.Item类来声明,定义它的属性为scrpy.item.Field对象,就像是一个对象关系映射(ORM).
我们通过将需要的item模型化,来控制从dmoz.org获得的站点数据,比如我们要获得站点的名字,url和网站描述,我们定义这三种属性的域。要做到这点,我们编辑在tutorial目录下的items.py文件,我们的Item类将会是这样
示例
1 | from scrapy.item import Item, Field |
**【3】**在[dirname]/spiders/
创建python文件 ¶
根目录输入命令,会自动创建
1 | scrapy genspider [name] [start_url] |
在里面编写爬虫类Spider,Spider是用户编写的用于从网站上爬取数据的类
- 创建一个自定义的Spider时,必须继承scrapy.Spider类,且定义以下三个属性:
-
name:用于区别不同的Spider。该名字必须是唯一的,不可以为不同的Spider设定相同的名字。
-
start_requests:包含了Spider在启动时进行爬取的URL列表。该函数必须返回Requests对象或者其生成器。
-
# Requests对象属性 print(type(response)) # scrapy.http.response.html.HtmlResponse print(type(response.text)) # str print(type(response.body)) # bytes print(response.encoding) # utf-8
1
2
3
4
5
6
7
8
9
10
11
12
- parse():这是Spider的一个默认回调函数。当下载器返回Response的时候,parse()函数就会被调用,每个初始URL完成下载后生成的Response对象将会作为唯一的参数传递给parse()函数。该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的Request对象。
#### **【4】**开始爬取
在scrapy项目根目录执行命令`scrapy crawl [obj_name]`,其中`obj_name`是python文件自定义类里的name值
也可以在项目根目录创建`main.py`文件
```python
from scrapy.cmdline import execute
execute("scrapy crawl [obj_name]".split())
-
-
1 | # 命令行执行 |
Scrapy shell ¶
根目录执行命令
-
加载网页(参数url需要加双引号)
1
scrapy shell url
加载网页成功后,response回应存储在本地变量response中
response.body
:获得网页html代码response.headers
:获得网页的header部分信息
Selector选择器 ¶
选择器包scrapy.selector.Selector
- response.selector.xpath():xPath选择器;也可省略写成
.xpath():
会返回一系列selectors - response.selector.css():CSS选择器;也可省略写成
.css()
:会返回一系列selectors - response.selector.extract():返回一个unicode字符串,为选中的数据
- response.selector.re():正则表达式选择器,返回字符串
请求传参 ¶
爬取的内容不再同一页面,
用parse函数最后yield scrapy.http.Request来调用一个更深的页面(自己定义函数)
图片爬取 ¶
管道类需要继承ImagesPipeLine
类
使用前需要先导入包
1 | from scrapy.pipelines.images import ImagesPipeline |
需要在settings.py
中指定图片存储路径
selenium ¶
基于浏览器 自动化测试模块
selenium-python中文文档 (python-selenium-zh.readthedocs.io)
安装 ¶
1 | python -m pip install selenium |
使用 ¶
1 | from selenium import webdriver |
webdriver.Chrome类对象
属性 | 含义 |
---|---|
.page_source |
获取浏览器当前页面的html源码数据 |
方法 | 含义 |
---|---|
.get(url) |
打开网址 |
.quit() |
关闭浏览器 |
.close() |
关闭当前标签 |
.find_element_by_xpath() |
使用xpath来寻找元素 |
.find_element_by_id/name() |
通过属性值id或者name值来寻找 |
.execute_script() |
执行js代码 |
.back() |
网页后退 |
.dorward() |
网页前进 |
WebElement类对象
属性/方法 | 含义 |
---|---|
.get_attribute() |
得到标签属性的值 |
.send_keys() |
写入内容 |
定位元素 ¶
-
根据Id属性值定位:返回第一个name属性匹配的元素,如果没有元素匹配,会抛出
NoSuchElementException
异常。-
login_form = driver.find_element_by_id('loginForm')
1
2
3
4
5
- 根据Name属性值定位:同上
- ```python
continue = driver.find_element_by_name('continue')
-
-
使用XPath定位:
-
clear_button = driver.find_element_by_xpath("")
1
2
3
4
5
6
- 使用链接文本定位超链接:
- ```python
continue_link = driver.find_element_by_link_text('Continue')
continue_link = driver.find_element_by_partial_link_text('Conti') -
参数即为 a标签内的文字
-
-
标签名定位
-
heading1 = driver.find_element_by_tag_name('h1')
1
2
3
4
5
- class定位
- ```python
content = driver.find_element_by_class_name('content') -
只返回匹配的第一个
-
-
css选择器定位
-
content = driver.find_element_by_css_selector('p.content')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
### 等待事件
#### 显式等待
显式的`waits`等待一个确定的条件触发然后才进行更深一步的执行。最糟糕的的做法是`time.sleep()`,这指定的条件是等待一个指定的时间段。 这里提供一些便利的方法让你编写的代码只等待需要的时间,`WebDriverWait`结合`ExpectedCondition`是一种实现的方法:
```python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delay_loading")
try:
element = WebDriverWait(driver,10).until(
EC.presence_of_element_located((By.ID,"myDynamicElement"))
)
finally:
driver.quit()
-
这段代码会等待10秒,如果10秒内找到元素则立即返回,否则会抛出TimeoutException
异常,WebDriverWait默认每500毫秒调用一下ExpectedCondition
直到它返回成功为止。ExpectedCondition
类型是布尔的,成功的返回值就是true,其他类型的ExpectedCondition
成功的返回值就是 not null
隐式等待 ¶
当我们要找一个或者一些不能立即可用的元素的时候,隐式waits
会告诉WebDriver轮询DOM指定的次数,默认设置是0次。一旦设定,WebDriver对象实例的整个生命周期的隐式调用也就设定好了。
1 | from selenium import webdriver |
行为链 ¶
更多函数查阅7. WebDriver API — Selenium Python Bindings 2 documentation (selenium-python.readthedocs.io)
1 | from selenium.webdriver import ActionChains #导入类 |
frame切换/窗口切换 ¶
-
需要定位iframe标签内部标签(子页面)
-
需要先切换到子页面
-
bro.switch_to.frame([id]) #先切换作用域再定位
1
2
3
4
5
- 切换回主页面
- ```python
wd.switch_to.default_content()
-
-
切换到新窗口
-
for handle in wd.window_handles: # 先切换到该窗口 wd.switch_to.window(handle) # 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口 if '窗口标题字符串' in wd.title: # 如果是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环, break
1
2
3
4
5
6
7
8
- 切换回旧窗口:先保存旧窗口句柄,然后再切换
- ```python
# mainWindow变量保存当前窗口的句柄
mainWindow = wd.current_window_handle
#通过前面保存的老窗口的句柄,自己切换到老窗口
wd.switch_to.window(mainWindow)
-
选择框 ¶
radio 单选框 ¶
1 | <div id="s_radio"> |
1 | # 获取当前选中的元素 |
checkbox 复选框 ¶
1 | <div id="s_checkbox"> |
1 | # 先把 已经选中的选项全部点击一下 |
select ¶
-
select_by_value
:根据选项的 value属性值,选择元素。-
# <option value="foo">Bar</option> s.select_by_value('foo')
1
2
3
4
5
6
7
8
9
- `select_by_index`:根据选项的 **次序**(从0开始),选择元素
- `select_by_visible_text`:根据选项的 **可见文本**,选择元素
- ```python
# <option value="foo">Bar</option>
s.select_by_visible_text('Bar')
-
-
deselect_by_value
:根据选项的value属性值, 去除选中元素 -
deselect_by_index
:根据选项的次序,去除选中元素 -
deselect_by_visible_text
:根据选项的可见文本,去除选中元素 -
deselect_all
:去除选中所有元素
select 单选下拉框 ¶
1 | # 导入Select类 |
select 多选框 ¶
多选框同
图形界面 ¶
pyside2 ¶
安装 ¶
1 | python -m pip install pyside2 |
控件 ¶
按钮 ¶
QPushButton
就是常见的按钮
信号:被点击 ¶
当按钮被点击就会发出 clicked
信号,可以这样指定处理该信号的函数
1 | button.clicked.connect(handleCalc) |
方法:改变文本 ¶
代码中可以使用 setText
方法来改变按钮文本,比如
1 | button.setText(text) |
方法:禁用、启用 ¶
所有控件(继承自QWidget类)都支持 禁用和启用方法。
禁用后,该控件不再处理用户操作
- 禁用
1 | button.setEnabled(False) |
- 启用
1 | button.setEnabled(True) |
单行文本框 ¶
QLineEdit
是只能单行编辑的文本框。
信号:文本被修改 ¶
当文本框中的内容被键盘编辑,被点击就会发出 textChanged
信号,可以这样指定处理该信号的函数
1 | edit.textChanged.connect(handleTextChange) |
信号:按下回车键 ¶
当用户在文本框中任何时候按下回车键,就会发出 returnPressed
信号。
有时我们需要处理这种情况,比如登录界面,用户输完密码直接按回车键就进行登录处理,比再用鼠标点击登录按钮快捷的多。
可以指定处理 returnPressed 信号,如下所示
1 | passwordEdit.returnPressed.connect(onLogin) |
方法:获取文本 ¶
通过 text
方法获取编辑框内的文本内容,比如
1 | text = edit.text() |
方法:设置提示 ¶
通过 setPlaceholderText
方法可以设置提示文本内容,比如
1 | edit.setPlaceholderText('请在这里输入URL') |
方法:设置文本 ¶
通过 setText
方法设置编辑框内的文本内容为参数里面的文本字符串,比如
1 | edit.setText('你好,白月黑羽') |
原来的所有内容会被清除
方法:清除所有文本 ¶
clear
方法可以清除编辑框内所有的文本内容,比如
1 | edit.clear() |
方法:拷贝文本到剪贴板 ¶
copy
方法可以拷贝当前选中文本到剪贴板,比如
1 | edit.copy() |
方法:粘贴剪贴板文本 ¶
paste
方法可以把剪贴板内容,拷贝到编辑框当前光标所在处,比如
1 | edit.paste() |
多行纯文本框 ¶
QPlainTextEdit
是可以 多行
的纯文本编辑框。
信号:文本被修改 ¶
当文本框中的内容被键盘编辑,被点击就会发出 textChanged
信号,可以这样指定处理该信号的函数
1 | edit.textChanged.connect(handleTextChange) |
信号:光标位置改变 ¶
当文本框中的光标位置变动,就会发出 cursorPositionChanged
信号,可以这样指定处理该信号的函数
1 | edit.cursorPositionChanged.connect(handleChanged) |
方法:获取文本 ¶
通过 toPlainText
方法获取编辑框内的文本内容,比如
1 | text = edit.toPlainText() |
获取选中文本 ¶
1 | #### 获取 QTextCursor 对象 |
方法:设置提示 ¶
通过 setPlaceholderText
方法可以设置提示文本内容,比如
1 | edit.setPlaceholderText('请在这里输入薪资表') |
方法:设置文本 ¶
通过 setPlainText
方法设置编辑框内的文本内容 为参数里面的文本字符串,比如
1 | edit.setPlainText('''你好,白月黑羽 |
原来的所有内容会被清除
方法:在末尾添加文本 ¶
通过 appendPlainText
方法在编辑框末尾添加文本内容,比如
1 | edit.appendPlainText('你好,白月黑羽') |
注意:这种方法会在添加文本后 自动换行
方法:在光标处插入文本 ¶
通过 insertPlainText
方法在编辑框末尾添加文本内容,比如
1 | edit.insertPlainText('你好,白月黑羽') |
注意:这种方法 不会
在添加文本后自动换行
方法:清除所有文本 ¶
clear
方法可以清除编辑框内所有的文本内容,比如
1 | edit.clear() |
方法:拷贝文本到剪贴板 ¶
copy
方法可以清除编辑框内所有的文本内容,比如
1 | edit.copy() |
方法:粘贴剪贴板文本 ¶
paste
方法可以把剪贴板内容,拷贝到编辑框当前光标所在处,比如
1 | edit.paste() |
文本浏览框 ¶
QTextBrowser
是 只能查看文本
控件。
通常用来显示一些操作日志信息、或者不需要用户编辑的大段文本内容。
该控件 获取文本、设置文本、清除文本、剪贴板复制粘贴 等等, 都和上面介绍的 多行纯文本框是一样的。
下面我们主要讲解不同点
方法:在末尾添加文本 ¶
通过 append
方法在编辑框末尾添加文本内容,比如
1 | textBrowser.append('你好,白月黑羽') |
有时,浏览框里面的内容长度超出了可见范围,我们在末尾添加了内容,往往希望控件自动翻滚到当前添加的这行,
可以通过 ensureCursorVisible
方法来实现
1 | textBrowser.append('你好,白月黑羽') |
注意:这种方法会在添加文本后 自动换行
方法:在光标处插入文本 ¶
通过 insertPlainText
方法在编辑框末尾添加文本内容,比如
1 | edit.insertPlainText('你好,白月黑羽') |
注意:这种方法 不会
在添加文本后自动换行
文本标签 ¶
QLabel
就是常见的标签
方法:改变文本 ¶
代码中可以使用 setText
方法来改变标签文本内容,比如
1 | button.setText(text) |
显示图片 ¶
QLabel可以用来显示图片,有时一个图片可以让界面好看很多
怎么用QLabel 显示图片呢?
可以在 Qt Designer上 属性编辑器 QLabel 栏 的 pixmap 属性设置中选择图片文件指定。
组合选择框 ¶
QComboBox
是组合选择框
信号:选项改变 ¶
如果用户操作修改了QComboBox中的选项就会发出 currentIndexChanged
信号,可以这样指定处理该信号的函数
1 | cbox.currentIndexChanged.connect(handleSelectionChange) |
方法:添加一个选项 ¶
代码中可以使用 addItem
方法来添加一个选项到 末尾
,参数就是选项文本
1 | cbox.addItem('byhy') |
方法:添加多个选项 ¶
代码中可以使用 addItems
方法来添加多个选项到 末尾
,参数是包含了多个选项文本的列表
1 | cbox.addItems(['byhy','白月黑羽','python教程']) |
方法:清空选项 ¶
代码中可以使用 clear
方法来清空选项,也就是删除选择框内所有的选项
1 | cbox.clear() |
方法:获取当前选项文本 ¶
代码中可以使用 currentText
方法来获取当前 选中的选项
的文本,比如
1 | method = cbox.currentText() |
列表 ¶
QListWidget
是列表控件
方法:添加一个选项 ¶
代码中可以使用 addItem
方法来添加一个选项到 末尾
,参数就是选项文本
1 | listWidget.addItem('byhy') |
方法:添加多个选项 ¶
代码中可以使用 addItems
方法来添加多个选项到 末尾
,参数是包含了多个选项文本的列表
1 | listWidget.addItems(['byhy','白月黑羽','python教程']) |
方法:删除一个选项 ¶
代码中可以使用 takeItem
方法来删除1个选项,参数是该选项所在行
1 | listWidget.takeItem(1) |
就会删除第二行选项
方法:清空选项 ¶
代码中可以使用 clear
方法来清空选项,也就是删除选择框内所有的选项
1 | listWidget.clear() |
方法:获取当前选项文本 ¶
currentItem
方法可以得到列表当前选中项对象(QListWidgetItem) ,再调用这个对象的 text
方法,就可以获取文本内容,比如
1 | listWidget.currentItem().text() |
就获取了 第1行,第1列
的单元格里面的文本。
1 | listWidget.currentItem().text() |
表格 ¶
QTableWidget
是表格控件
创建列 和 标题栏 ¶
我们可以通过 Qt designer 为一个表格创建列和对应的标题栏。
只需要双击 Qt designer 设计的窗体中的 表格控件, 就会出现这样的对话框。
在 列
标签栏中,点击左下角的加号,就可以为 添加一个列,并且设置标题栏名称。
方法:设置表格行数 ¶
代码中可以使用 setRowCount
方法来设置表格行数,比如
1 | table.setRowCount(10) |
方法:获取所有行数 ¶
代码中可以使用 rowCount
方法来获取表格所有的函数,比如
1 | rowcount = table.rowCount() |
方法:获取当前选中是第几行 ¶
代码中可以使用 currentRow
方法来获取当前选中是第几行,比如
1 | currentrow = table.currentRow() |
注意:行数是从0开始的, 第一行的行数是 0
方法:插入一行、删除一行 ¶
insertRow
方法可以在指定位置插入一行,比如
1 | table.insertRow(0) |
就插入一行到第 1
行这个位置, 表格原来第1行(包括原来的第1行)以后的内容,全部往下移动一行。
1 | table.insertRow(2) |
就插入一行到第 3
行这个位置, 表格原来第3行(包括原来的第3行)以后的内容,全部往下移动一行。
removeRow
方法可以删除指定位置的一行,比如
1 | table.removeRow(0) |
就删除第 1
行, 表格原来第1行以后的内容,全部往上移动一行。
1 | table.removeRow(2) |
就删除第 3
行, 表格原来第3行以后的内容,全部往上移动一行。
方法:清除/删除所有内容 ¶
clearContents
方法可以清除表格所有的内容,比如
1 | table.clearContents() |
清除后,仍然会留下表格栏
如果连表格栏都要删除,可以加上 setRowCount(0)
,像这样
1 | table.clearContents() |
方法:获取单元格文本的内容 ¶
item
方法可以指定位置的单元格对象(QTableWidgetItem) ,再调用这个对象的 text
方法,就可以获取文本内容,比如
1 | table.item(0,0).text() |
就获取了 第1行,第1列
的单元格里面的文本。
1 | table.item(2,4).text() |
就获取了 第3行,第5列
的单元格里面的文本。
方法:设置单元格文本内容 ¶
qt表格的单元格内的内容对象 是一个 单元格对象 QTableWidgetItem
实例
如果单元格 没有被设置过
内容,可以这样
1 | from PySide2.QtWidgets import QTableWidgetItem |
也可以简写为
1 | from PySide2.QtWidgets import QTableWidgetItem |
如果单元格 已经被设置过
文本内容,
item
方法可以获取指定位置的 QTableWidgetItem ,再调用这个对象的 setText
方法,就可以设置单元格文本内容,比如
1 | table.item(0,0).setText() |
就设置了 第1行,第1列
的单元格里面的文本。
1 | table.item(2,4).setText() |
就设置了 第3行,第5列
的单元格里面的文本。
如果希望某个单元格为 只读,不允许修改,可以使用QTableWidgetItem对象的 setFlags
方法,像这样
1 | from PySide2.QtWidgets import QTableWidgetItem |
如果想文本内容 居中对齐,每个当对应的QTableWidgetItem 调用 setTextAlignment,如下
1 | from PySide2.QtWidgets import QTableWidgetItem |
方法:设定列宽、宽度自动缩放 ¶
Qt Designer 上目前没法拖拽设定 每个列的宽度,只能在代码中指定。
如下所示
1 | #### 设定第1列的宽度为 180像素 |
如想让 表格控件宽度 随着父窗口的缩放自动缩放,可以
在 属性编辑器 中 勾选 HorizontalHeaderStretchLastSection
或者使用下面代码
1 | table.horizontalHeader().setStretchLastSection(True) |
信号:单元格内容改动 ¶
当用户修改了一个单元格的内容,会发出 cellChanged
信号,并且携带参数指明该单元格的行号和列号。
我们的代码可以对该信号进行相应的处理。
示例代码如下
1 | def __init__(self): |
单选按钮 和 按钮组 ¶
QRadioButton
是单选按钮
说明 ¶
同一个父窗口
里面的多个单选按钮,只能选中一项。
如果你有多组单选按钮, 每组都应该有不同的父控件,或者不同的Layout。
通常建议:多组单选按钮,放到不同的 按钮组 QButtonGroup
中,按钮组就是父控件
信号:选中状态改变 ¶
如果用户操作点击了按钮组 QButtonGroup
中的一个按钮, QButtonGroup 就会发出 buttonClicked
信号,可以这样指定处理该信号的函数
1 | buttongroup.buttonClicked.connect(handleButtonClicked) |
然后,在处理函数中调用QButtonGroup对象的 checkedButton()
函数,返回值就是被选中的按钮对象。
再调用这个返回的按钮对象的 text()
方法得到界面文本,就可以知道是哪个选项被选中了。
勾选按钮 和 按钮组 ¶
QCheckBox
是勾选按钮
说明 ¶
通常建议:多组勾选按钮,放到不同的 按钮组 QButtonGroup
中,按钮组就是父控件。
信号:选中状态改变 ¶
如果用户操作点击了按钮组 QButtonGroup
中的一个按钮, QButtonGroup 就会发出 buttonClicked
信号,可以这样指定处理该信号的函数
1 | buttongroup.buttonClicked.connect(handleButtonClicked) |
然后,在处理函数中调用QButtonGroup对象的 checkedButton()
函数,返回值就是被选中的按钮对象。
再调用这个返回的按钮对象的 text()
方法得到界面文本,就可以知道是哪个选项被选中了。
tab页控件 ¶
我们可以通过tab页控件把界面分为好几各页面
通过Qt designer 只需要拖拽控件到各个页面即可。
要修改tab页的标题,可以先点击该tab页,然后在属性编辑器currentTabText
修改
tab页中布局Layout ¶
如果我们要在tab页上布局, 你可能会在对象查看器总直接右键点击该tab,可以你会发现 右键菜单里面没有布局项。
这是 Qt designer 非常坑爹的地方,我当时足足花了一个小时才找到方法。
- 首先需要你在tab页上添加一个控件
- 然后点击 在对象查看器 右键点击上层 TabWidget ,这时,你就会发现有布局菜单了
进度条 ¶
QProgressBar
是进度条,如下图所示
说明 ¶
进度条也是一个常用的控件,当程序需要做一件比较耗费时间的任务(比如统计数据,下载文件等)时,可以用来向用户指示操作的进度。
而且有了进度显示,用户就知道应用程序仍在运行,并没有出问题。
QProgressBar进度条把每个进度称之为一个step(步骤)。
我们可以通过它的 setRange
方法设定步骤个数,比如
1 | progressBar.setRange(0,5) |
就设定了,进度分为5步。
然后,通过 setValue
方法,指定当前完成到了哪一步,比如
1 | progressBar.setValue(3) |
就表示完成了 3/5, 也就是 60%, 进度条就会显示60%的进度。
可以使用reset()将进度条倒退到开头。
有时候我们的任务没法知道完成了多少,比如下载一个未知大小的文件。
这时,可以把range 范围都设置为0,这样,进度条会显示忙碌指示符,而不是显示进度百分比。
下面是一个进度条程序的示例代码
1 | from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QProgressBar,QMessageBox |
上面的代码,运行时,会有很多告警,因为我们在新线程中操作界面对象,容易出问题。
更合理的方法是通过信号,在线程之间传递信息,对界面的操作都在主线程中完成。
如下
1 | from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QProgressBar,QMessageBox |
数字输入框 ¶
QSpinBox
是数字输入框,可以输入或使用上下箭头选择数字
获取数字 ¶
通过 value
方法获取编辑框内的文本内容,比如
1 | number = box.value() |
注意:返回的是整数对象,不是字符串
方法:设置数字 ¶
通过 setValue
方法可以设置提示文本内容,比如
1 | box.setValue(100) |
日期控件 ¶
QDateEdit
类可以用来选择日期时间
获取日期 ¶
当用户点击日期时间控件并且选取了 日期和时间,后来程序要获取这个控件里面选定的日期时间,可以使用date方法获取日期对象。
如下所示
1 | #### 返回 PySide2.QtCore.QDate 对象 |
QDate 对象的具体说明参考官方文档
选择文件框 ¶
QFileDialog
类可以用来选择文件或者目录
选择目录 ¶
通过 getExistingDirectory 静态方法
选择目录。
该方法,第一个参数是父窗口对象,第二个参数是选择框显示的标题。
比如
1 | from PySide2.QtWidgets import QFileDialog |
返回值即为选择的路径字符串。
如果用户点击了 选择框的 取消选择按钮,返回 空字符串。
选择单个文件 ¶
如果你想弹出文件选择框,选择一个 已经存在
的文件,可以使用 QFileDialog 静态方法 getOpenFileName
,比如
1 | from PySide2.QtWidgets import QFileDialog |
该方法返回值 是一个元组,第一个元素是选择的文件路径,第二个元素是文件类型,如果你只想获取文件路径即可,可以采用上面的代码写法。
如果用户点击了 选择框的 取消选择按钮,返回 空字符串。
如果你想弹出文件选择框,选择路径和文件名,来 保存一个文件
,可以使用 QFileDialog 静态方法 getSaveFileName
,比如
1 | from PySide2.QtWidgets import QFileDialog |
选择多个文件 ¶
如果要选择多个文件,使用 getOpenFileNames 静态方法
1 | from PySide2.QtWidgets import QFileDialog |
上例中 filePaths 对应的返回值是一个列表,里面包含了选择的文件。
如果用户点击了 选择框的 取消选择按钮,返回 空列表。
库方法 ¶
random 库 ¶
函数/方法 | 参数 | 返回值/作用 |
---|---|---|
random.choice() | 一个序列 | 随机返回序列中的一个元素 |