Python学习笔记-正则与数据库

学习路线方面应该差不多就先到这吧,毕竟也开学啦,后面的内容感觉挺深的,对web开发目前没啥兴趣,比较在意的就是多线程了…..
开始着重看下爬虫和数据挖掘方面吧

Py的语法真的好优雅,一袋能顶两袋撒~~23333

正则-re模块

Python提供re模块,包含所有正则表达式的功能。由于Python的字符串本身也用\转义,所以要特别注意\\表示\
因此强烈建议使用Python的r前缀,就不用考虑转义的问题了,r代表没有转义,还可以跟一个参数如使用re.I表示不区分大小写

1
2
3
4
5
6
7
8
9
10
11
import re
pa = re.compile(r'^\d+$')
# pa = re.compile(r'^Abcd$',re.I)
ma = pa.math(str)
# 上面的两句可以合为一句
# ma = re.math(r'abc',str)

if ma:
print(ma)
else:
print("无匹配")

match()方法判断是否匹配(从头开始匹配),如果匹配成功,返回一个Match对象,否则返回None
如果正则表达式中定义了组,通俗说就是使用了小括号,那么就可以在Match对象上用group()方法提取出子串来。需要注意的是group(0)永远是原始字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import re
pa = re.compile(r'^(\d{2})-(\d{3,4})$')
ma = pa.match('43-1234')

if ma:
print(ma.group(0))
print(ma.group(1))
print(ma.groups())
else:
print("无匹配")

# 结果:
# 43-1234
# 43
# ('43', '1234')

贪婪匹配与非贪婪匹配

最后需要特别指出的是,正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。举例如下,匹配出数字后面的0

1
2
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')

由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。
必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:

1
2
>>> re.match(r'^(\d+?)(0*)$', '102300').groups()
('1023', '00')

非贪婪匹配,尽可能的少匹配
xx*? 匹配零次
因为可以是0次或任意次,*最少那就是0咯

xx+? 匹配一次
+可以是1次或任意次,最少就是1次咯

拓展之split与编译

如果我们用传统的split切割是没办法切割多个空格的,因为这是不确定事件,但是如果用正则就很简单了
re.split(r'\s+', 'a b c') ,无论多少个空格都切给你看

编译器处理正则的过程是首先把正则式子进行编译,如果不符合规范会报错,然后再进行比较
记得上面说过两种方式,可以直接用math或者拆成2步先compile以下,这里的compile就相当于编译了
如果你的正则要复用,还是拆开比较好,效率会高一点

操作MySQL

python3.5以下的使用MySQLdb,官方下载地址:https://www.python.org/dev/peps/pep-0249/,安装无难度
python 3.5以上的需要把MySQLdb换成pymysql,使用pip直接安装即可pip install PyMySQL

这里主要使用到了2个对象,connect和cursor;conn相当于在客户端和服务器直接修了一条路,cur是运输的货车,当然它也是有可能出现异常的
这个模块默认是关闭自动commit,避免一句sql当作一个事务,所以增删改需要commit哦,目前我的环境是3.5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pymysql

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='test', charset='UTF8')
# 关闭自动commit
# conn.autocommit(False)
cur = conn.cursor()
try:
cur.execute("insert into temp(name) values('测试')")
conn.commit()
print("执行完毕!")
except Exception as e:
print(e)
# 出现异常回滚操作
conn.rollback()

cur.close()
conn.close()

然后是关于一些简单的查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import pymysql

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='test', charset='UTF8')
cur = conn.cursor()
cur.execute("select * from temp")

# 返回的数据是元组的元组,可以进行遍历
# for i in cur:
# print("id:%d 姓名:%s" %i)

# 返回多少行(增删改中是影响的行数)
print(cur.rowcount)
# 返回一行数据,将指针移动一行
rs = cur.fetchone()
print(rs)
# 返回指定的行数 对于当前指针位置
rs = cur.fetchmany(3)
print(rs)
# 返回全部,当前指针位置到最后
rs = cur.fetchall()
print(rs)

cur.close()
conn.close()

关于sqlite

SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成。
Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 导入SQLite驱动:
>>> import sqlite3
# 连接到SQLite数据库
# 数据库文件是test.db
# 如果文件不存在,会自动在当前目录创建:
>>> conn = sqlite3.connect('test.db')

>>> cursor = conn.cursor()
>>> cursor.execute('create table user (id varchar(20) primary key, name varchar(20))')
<sqlite3.Cursor object at 0x10f8aa260>
>>> cursor.execute('insert into user (id, name) values (\'1\', \'Michael\')')
<sqlite3.Cursor object at 0x10f8aa260>
# 通过rowcount获得插入的行数:
>>> cursor.rowcount
1

>>> cursor.close()
>>> conn.commit()
>>> conn.close()

mysql的占位符是%s,sqlite用?

(‘select from %s’ %(‘temp’,))
(‘select
from ?’,(‘temp’,))
好吧,我被坑了

关于对象的补充

对象、类这一块不可能上次写的那么一点就能概况,这里提下我比较有疑惑的问题:关于继承中的super

super(SubClass, self).method() 的意思是,根据self(站在self的角度)去找SubClass的‘父亲’,然后调用这个‘父亲’的method()

角度问题很重要,不像Java,Python是支持多继承的,那么就不可避免有这个问题
首先要明确的是:当一个类从多个类继承的时候,按照从左到右的顺序继承。比如
class test(A,B),编译器理解为test的父亲是A,A的父亲是B….这样说可能不太严谨,但是我不知道怎么形容了
在test的角度A的父亲就是B,即便A可能还继承了C;当切换到A的角度,A的父亲就是C了
理解了这些就能理解super的这种奇怪的用法了

在python3 中做了个简化,如果你在类定义的语句块内写一个不带参数的super(),则相当于写了 super(本类名,self);因为这样的用法比较多嘛~~

推荐2篇文章
Python和java中的super
python 的 super,一次性整明白

喜欢就请我吃包辣条吧!

评论框加载失败,无法访问 Disqus

你可能需要魔法上网~~