美文网首页我爱编程
Python 高级(第一,第二,第三课)

Python 高级(第一,第二,第三课)

作者: 小小小小饼 | 来源:发表于2018-04-16 16:56 被阅读33次

    Python 高级

    同样还是学习@斌叔的程序媛课程的笔记~

    第一第二第三课已经完成,第四课运行不成功(可能因为我用得是Python3, 斌叔用得是Python2吧)
    ---------------------------------------我是分割线-----------------------------------------------
    第一课:

    正则表达式:对字符串操作的一种逻辑公司(判断电话号码,邮箱等)

    re模块

    一般使用步骤是先把正则表达式的字符串换成Pattern 对象,接着用这个对象处理文本并得到匹配结果,最后根据结果信息,进行其他的操作

    代码:(请参看注释)
    
    import re #导入 re 模块
    
    pattern = re.compile(r'Hello') #将正则表达式转换为 Pattern 对象
    
    match = pattern.match('Hello cxy61!') #使用 pattern 匹配文本,获得结果,不匹配时结果为None
    
    print(match) #输出匹配结果
    
    if match:
    
    print(match.group()) #输出分组信息
    
    else:
    
    print("No match.")
    
    print (u"以上是匹配有结果的事例")
    
    print (u"******************")
    
    print (u"以下是无匹配结果的事例")
    
    pattern2 = re.compile(r'Python')
    
    match2 = pattern2.match('Hello cxy61')
    
    print(match2)
    
    if match2:
    
    print(match2.group())
    
    else:
    
    print("No match.")
    
    
    运行:
    Screen Shot 2018-04-03 at 4.50.41 PM.png.png

    match() 和 search() 对比

    match() 只匹配字符串的起始,如果开始不匹配,便会返回 None,而 search() 是从头至尾对字符串进行匹配


    Screen Shot 2018-04-03 at 5.01.11 PM.png.png

    sub() 替换方法

    
    import re
    
    time = "2018-04-03"
    
    pattern = re.compile(r'\D') # \D 表示匹配任意非数字
    
    sub = pattern.sub("/",time) # sub(替换后的字符,要匹配的字符串)
    
    print(sub)
    
    print(re.sub(r'\D',"/",time)) # 也可以简写成这样
    
    

    结果:2018/04/03

    遇到问题:判断是否是电话号码时

    issue : name 'raw_input' is not defined

    python 3.0 之后已经用input代替了

    
    import re
    
    # 正则匹配电话号码
    
    phone = input("phone number:")
    
    pattern = re.compile('^0\d{2,3}\d{7,8}$|^1[3578]\d{9}$|^147\d{8}$')
    
    match = pattern.match(phone)
    
    if match:
    
    print(match.group())
    
    else:
    
    print("error")
    
    
    Screen Shot 2018-04-03 at 5.23.07 PM.png.png

    正则表达式参考文档:http://www.regexlab.com/zh/regref.htm

    第二课:数据库操作

    要完成的任务如下:

    Screen Shot 2018-04-04 at 11.25.15 AM.png.png

    在初级课程中,是以.TXT 格式存在了文件夹中,这次我们以数据库来进行保存

    要用到 sqlit3 模块,它是Python 的内置模块,可以满足我们对数据的操作

    import sqlite3
    
    connect = sqlite3.connect("test_sqlite.db")
    
    connect.close()
    

    connect 后接数据库名称,若没有该数据库,则自动创建数据库,若存在该数据库,则链接数据库,再进行后续操作

    你可以再运行前后使用 ls 命令查看当前文件目录,这个 test.db 就是刚创建的数据库

    操作完数据库,要用 close() 方法关闭数据库,动手试试吧

    上代码:

    import sqlite3 #导入sqlite3 模块
    
    connect = sqlite3.connect("test_sqlite.db") #创建数据库
    
    cursor = connect.cursor() # 创建游标,以便用sql语句
    

    创建一个名为diary的表,并设置一个ID 为自增主键,title,content 为text类型

    cursor.execute("drop table diary")
    
    cursor.execute("CREATE TABLE diary (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT , content TEXT)")
    

    向表中插入数据,因为是自增主键,id可以写为NULL,表中id值会是1,2,3递增

    cursor.execute("INSERT INTO diary VALUES (NULL,'title1','content1') ")

    或者可以这样写

    cursor.execute("INSERT INTO diary(title,content) VALUES ('title2','content2')")

    查询表中所有数据,并输出

    for row in cursor.execute("SELECT * FROM diary"):
    
    print(row)
    
    print(u"***** 增 ***** \n")
    

    删除表中 id 为1的数据

    cursor.execute("DELETE FROM diary WHERE id = 1")

    在输出所有数据,以验证是否成功

    for row in cursor.execute("SELECT * FROM diary"):
    
    print(row)
    
    print(u"***** 删 ***** \n")
    

    修改 id 为2的数据

    cursor.execute("UPDATE diary SET title = 'title0', content = 'content0' WHERE id = 2")

    再输入所有数据,验证是否修改成功

    for row in cursor.execute("SELECT * FROM diary"):
    
    print(row)
    
    print(u"***** 改 ***** \n")
    
    #插入多条数据,供查看
    
    items = [("title0","content0"),("title1","content1"),("title2","content2")]
    
    #executeman 一次向标准插入多条数据
    
    cursor.executemany("INSERT INTO diary(title,content) VALUES (?,?)",items)
    
    print(u"插入多条数据后的表:")
    
    for row in cursor.execute("SELECT * FROM diary"):
    
    print(row)
    #查
    
    print(u"查 id 为5 的数据:")
    
    cursor.execute("SELECT * FROM diary WHERE id = 5")
    
    print(cursor.fetchall())
    
    print(u"查 title 为 title0 的数据:")
    
    cursor.execute("SELECT * FROM diary WHERE title = 'title0' ")
    
    print(cursor.fetchall())
    
    cursor.close() #关闭游标和数据库
    
    connect.close()
    
    

    运行结果:

    Screen Shot 2018-04-06 at 11.25.25 AM.png.png

    小知识补充:

    进行“查”操作时,fetchall() 方法可以得到符合条件的所有数据

    表中数据除了主键值以外,其他键值是可以重复的

    遇到issue:
    cursor.execute("CREATE TABLE diary (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT , content TEXT)")
    
    sqlite3.OperationalError: table diary already exists
    
    解决方法:

    在第八行前加入 ‘cursor.execute("drop table diary")’ 这句代码

    解决方法来自torresFans的代码

    继续学习:

    一个数据库是可以创建多张表的,但是表名不能重复,如果重复将报错无法创建

    如何解决这个问题呢?

    首先我们先要获取当前数据库中所有的表,来看下面的代码

    代码:

    import sqlite3
    
    connect = sqlite3.connect("test_sqlite.db")
    
    cursor = connect.cursor()
    
    cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table'")
    
    for item in cursor.fetchall():
    
    print(item)
    
    

    就可以读出之前创建的数据库所有的表了


    Screen Shot 2018-04-06 at 3.22.41 PM.png.png

    每个数据库中都有一个名为 sqlite_master 的内置表,它储存着所有的表信息,动手试试吧

    Screen Shot 2018-04-09 at 11.00.23 AM.png.png

    从输出结果我们可以看到,每项都是一个元组,那么拿到表名只需要将输出改成这样即可

    print item[0]

    
    import sqlite3
    
    connect = sqlite3.connect("test_sqlite.db")
    
    cursor = connect.cursor()
    
    # cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table'")
    
    # for item in cursor.fetchall():
    
    # print(item)
    
    #搜索表,若存在,则返回True, 反之返回 False
    
    def searchTabel(str):
    
    global cursor
    
    flag = False
    
    cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table'")
    
    for item in cursor.fetchall():
    
    if item[0] == str:
    
    flag = True
    
    break
    
    return flag
    
    #创建表,若不存在,则创建,反之给出提示信息
    
    def initTable(str):
    
     global cursor
    
     if searchTabel(str) == False:
    
     sql = "create table",str,"(id INTEGER PRIMARY KEY AUTOINCREAMENT,tile TEXT,content TEXT)" 
    
     cursor.execute(sql)
    
     else:
    
     print(u"该表已存在")
    
    initTable("diary")
    
    

    我们一起把增删改查都写成函数的形式吧

    多了一步操作, connect.commit()

    这一步是对数据库操作事务的提交,之前没有加是为了方便程序的输出演示,在进行插入、修改和删除之后,要进行事务的提交.

    这样才能真正的修改数据库中的数据,当然了查找操作就不必写了

    根据 ID 删除数据,参数分别为表名(字符串类型),数据(元祖类型)

    def inserData(name, tup):

    global connect

    global cursor

    sql = "INSERT INTO " + name + "(title, content) VALUES (?,?)"

    cursor.execute(sql, tup)

    connect.commit()

    根据 ID 删除数据,参数分别为表名(字符串类型),主键(整型)

    def deleteData(name, id):

    global connect

    global cursor

    sql = "DELETE FROM " + name + " WHERE id = " + str(id)

    cursor.execute(sql)

    connect.commit()

    根据 ID 修改数据,参数分别为表名(字符串类型),主键(整型),数据(元祖类型)

    def updateData(name, id, tup):

    global connect

    global cursor

    sql = "UPDATE " + name + " SET title = '" + tup[0] + "', content = '" + tup[1] + "'WHERE id = " + str(id)

    cursor.execute(sql)

    connect.commit()

    根据 id 查找数据,参数分别为表名(字符串类型),主键(整型)

    def searchData(name, id):

    global cursor

    sql = "SELECT * FROM " + name + " WHERE id = " + str(id)

    cursor.execute(sql)

    print(u"查找的数据为:",cursor.fetchone())

    注意:

    SQL语句,衔接的时候一定要记得加空格!!!

    使用:

    
    # 向diary 表中插入数据 ('title1','title2')
    
    inserData("diary",('title1','title2'))
    
    # 删除 diary 表中id 为 5 的数据
    
    deleteData("diary",5)
    
    # 将 diary 表中 ID 为18 数据修改为 ('title100','content100')
    
    updateData("diary",18,('title100','content100'))
    
    # 查找 diary 中 id 为 10 的数据
    
    

    第三课:网络编程

    需要用到 socket

    socket 是进程中的一种通信方式,可以用不同主机间的数据传输

    Python中内置有socket模块,我们需要应用该模块的socket()方法创建一个队象,然后再进行设置

    首先,新建一个server.py 文件作为我们的服务端

    
    import socket
    
    s = socket.socket() # 初始化 socket 对象
    
    s.bind(('127.0.0.1',1234)) # 绑定端口号为 1234
    
    s.listen(5) # 等待客户端连接
    
    while True:
    
    c, addr = s.accept() #客户端连接后,得到 connect 和 address
    
    print(u"连接地址为:",addr)
    
    c.send('成功连接至服务端。。。') # 向客户端发送消息
    
    c.close() # 关闭连接
    
    

    127.0.0.1 是我们的本地主机 IP,1234 是随意设置的一个端口号

    Screen Shot 2018-04-09 at 12.16.51 PM.png.png

    可能出现的情况,已经标注了出来

    lsof -i:1234

    1234 是你设置的端口号,可以查看占用该端口号的进程

    kill 80639

    80639 是查到进程的 PID

    遇到问题,如何杀死进程??

    写入 kill 80639

    好,运行成功后,这个终端不要关闭,再新打开一个终端,准备运行客户端

    再新建一个 client.py 文件作为我们的客户端

    
    import socket
    
    s = socket.socket()
    
    s.connect(('127.0.0.1',1234))
    
    print(s.recv(1024))
    
    s.close()
    
    

    运行 client.py

    遇到问题:c.send("成功连接至服务器。。。") # 向客户端发送消息

    TypeError: a bytes-like object is required, not 'str'

    这个send()方法不支持str,所以要把str 转为 bytes 类型

    解决:‘c.send(bytes("成功连接至服务器。。。",encoding = "utf8")) ’

    运行成功的截图:

    Screen Shot 2018-04-11 at 2.32.31 PM.png.png

    recv(2014) 表示最多接受1024字节的数据

    下面模拟以日记本为例子:

    client.py
    
    import socket
    
    s = socket.socket()
    
    s.connect(('127.0.0.1',1234))
    
    print(s.recv(1024))
    
    dict = {"title":"title","content":"content1"}
    
    # 不能发生字典数据,所以转为字符串后发送
    
    s.send(bytes(str(dict),encoding = "utf8"))
    
    s.close()
    
    
    server.py
    
    import socket
    
    s = socket.socket() # 初始化 socket 对象
    
    s.bind(('127.0.0.1',1234)) # 绑定端口号为 1234
    
    s.listen(5) # 等待客户端连接
    
    while True:
    
    c, addr = s.accept() #客户端连接后,得到 connect 和 address
    
    print(u"连接地址为:",addr)
    
    c.send(bytes("成功连接至服务器。。。",encoding = "utf8")) # 向客户端发送消息
    
    # eval() 将字符串转换为字典
    
    dict = eval(c.recv(1024))
    
    if dict:
    
    print(u"收到的数据为:",dict)
    
    print(u"日记的标题为:",dict["title"])
    
    print(u"日记的内容为:",dict["content"])
    
    c.close() # 关闭连接
    
    
    结果:(运行方式见上文)
    Screen Shot 2018-04-11 at 4.35.01 PM.png.png

    相关文章

      网友评论

        本文标题:Python 高级(第一,第二,第三课)

        本文链接:https://www.haomeiwen.com/subject/supekftx.html