2021-07-20 读书笔记:Python Web开发学习实录

读书笔记:Python Web开发学习实录

结于2021-07-20;
本书内容较老(2011),但覆盖交广,值得刷一遍;

前言

Python

  • 解释型语言;
  • 高效的数据结构
  • 支持面向对象编程
  • 语法简洁 支持动态数据类型

Python解释器容易通过C/C++来实现扩展;

本书内容:

  • Pyhton基础
  • 面向对象
  • 文件交互
  • 异常容错
  • 数据持久化
  • 网络功能
  • HTML文档解析
  • WxPython
  • Django

第1章 欢迎来到Python世界

特点:

  • 免费开源,简单易学,高级语言,解释执行(无需编译);
  • 可移植性,面向对象,嵌入型(脚本语言),可扩展,类库丰富;

Python解释器:

  • 源码 转换 字节码 翻译为计算机语言 执行;
  • Python解释器承担了内存管理器的工作;

应用:

  • 支持系统编程,图形化(PIL、TKinter)
  • 数字处理(numpy),文本处理(re SGML XML)
  • 数据库(Python DB-API接口模块),Python自带的Gadfly模块可提供完整的SQL环境
  • 网络编程:Socket
  • Web编程:HTML
  • 多媒体:PyGame(游戏开发)、yOpenGL(图像处理)

安装:

  • 在官网下载安装;(Linux系统已预装)
  • 配置环境变量;
  • 启动:命令行 或 IDLE;

解释器命令

  • -d:提供调试输出
  • -O:生成优化的字节码(.pyo)
  • others
# 设置编码
#-*- coding:UTF-8 -*-
# or use
# coding:utf-8

# 接收键盘录入的一个数字
x = int(raw_input("Please input ..."))

第2章 练就扎实的基本功

编码规则:

  • 代码缩进 与 冒号;
  • 代码缩进是一种语法;
  • 使用空行分隔代码;

类和对象:

  • 首字母大写,驼峰;
  • 私有属性方法 以两个下划线作为前缀;
class MyClass:
  __name = ''
  def __init__(self, name):
    self.__name = name
  def getName(self):
    return self.__name

if __name__ == "__main__":
  myClass = MyClass('haha')
  myClass.getName()

函数:

  • 函数名是区分大小写的;

注释:

  • 编码注释:# -*- coding:UTF-8 -*-,需要加在最前面;
  • 跨平台注释:如果需要Python程序运行在Windows以外平台,则需要在Python文件前加上注释说明 !# /usr/bin/python

python中用于语句结尾的分号可以省略;

数值

Python长整型受限于用户计算机的虚拟内存大小;

整数类型:

  • 整形:最大整数 sys.maxint、最小整数 -1-sys.maxint、八进制0开始、十六进制0x开始;
  • 长整型:在整数值后加个L/l;
  • 布尔型 True False

浮点数类型:

  • 双精度浮点型:-1.609E-19
  • 十进制浮点型:Decimal(1,3),无限不循环小数 or 分数,需要导入 decimal模块;

复数:0+2j

  • num.real 实部
  • num.imag 虚部
  • num.conjugate() 共轭复数

标识符的命名:

  • 以下划线开头的标识符具有特殊意义
  • 以单下划线开头的标识符代表不能直接访问的类属性;(通过接口暴露)
  • 以双下划线开头的标识符代表类的私有成员;(完全内部使用)
  • 以双下划线开头和结尾的标识符代表Python中特殊的专用标识;
  • 大小写敏感;

Python是动态类型语言,无需声明变量类型;(Python不支持C语言中的自增和自减运算)

字符串的标示函数:

  • str()函数:值转字符串,str(123456L) => 123456
  • repr()函数:以合法表达式形式表示值,repr(123456L) => 123456L
  • ' ' " " ''' ''' """ """ r''

输出与输入:

  • 输出 print()函数
  • 输入:input() 和 raw_input()函数
  • input()函数把输入默认为Python表达式;
  • raw_input()函数把读入的转为字符串;

算数运算

  • 基础运算:+ - * / % ** // 加减乘除 取余 幂 整除;
  • 关系运算:< > <= >= == != 或 <> 最后一个是不等于的两种形式;
  • 逻辑运算:and or not
  • 运算优先级:算数运算符 > 关系运算符 > 逻辑运算符
  • lambda也是一个运算符;

第3章 控制结构

if xxx:
  xxx
elif:
  xxx
else:
  xxx


while condation:
  xxx
else:
  xxx


for target in object:
  xxx
else:
  xxx

for循环还可以用于任何可迭代的对象;

文件迭代器:

  • 对于已经打开的文件对象,便具有两个方法 readline和next;
  • readline读到文件末尾,会返回空串;
  • next 在文件末尾时,不会返回空串,而会引发一个内置的 StopIteration异常;

所有迭代工具的内部工作都是在循环的调用next方法;

迭代器的使用:

  • for line in open('test.py'):
  • iter()函数,参数是一个可迭代对象;返回的是一个迭代器,然后就可以使用迭代器的next方法进行输出;

迭代

# 并行迭代
for i in range(len(names)):
  names[i],ages[i]

# 并行迭代
for name,age in zip(names,ages):

# 编号迭代
for index, item in enumerate(items):

跳转语句

支持:breakcontinue语句;

其他语句:

  • pass 占位符;
  • del 删除不再使用的对象、序列和字典元素;
  • exec 动态的创建python代码,并执行;

第4章 可复用的函数和模块

Python程序:

  • 包(package)、模块(module)、函数(function);

包:

  • 完成特定功能的工具箱;__init__.py是包的注册文件,标识当前文件夹是一个包;

函数:

  • def关键字 定义函数;
  • 无返回值时,默认返回None;
# 默认参数
def login(name='hello', pwd='world'):
  pass

# 可变参数
def login(* params):
  params[0]
# 调用
login(name, pwd)  

# 字典类型参数
def login(**params):
  params.keys()
# 调用
login(username="admin", pwd="password")

Coding:

strNum.isdigit() # 判断是否是数字 字符串

tuple([x, y, z]) # 数组转元组,x y z是三个变量

# 当前模块 某函数中 使用全局变量
num = 5
def myFun():
  global num # 这个num不再是局部的了
  num = num + 1

# 获取文件的编码方式
type = sys.getfilesystemencoding()
txt.decode('UTF-8').encode(type)

range(10)
randint(10,100)

# 类型转换
int('10')
str(500)
float('1.1')

模块调用:

# test1.py
def myFunc1():
  pass

class MyClass:
  def myClassFunc(self):
    pass

# main.py
import test1 # 先找当前路径,然后是lib目录、site-packages目录、环境变量设置的目录
# from test1 import myFunc1
# from test1 import *

test1.myFunc1()
test1.MyClass().myClassFunc()

模块属性介绍

  • __name__
    • 用于判断当前模块是不是程序的入口;
    • if __name__ == '__main__':
    • 否则就是被另一个模块调用;
  • __doc__
    • Python中模块是一个对象,每个对象都有一个该属性;
    • 输出文档字符串的内容;

模块内置函数

  • apply()函数:
    • apply(func_name,[, args [, kwargs]])
    • args:参数列表或元组
    • kwargs:字典类型的参数
    • 调用函数
  • filter()函数:
    • filter(func_name, sequence)
    • 过滤序列
  • reduce()函数:
    • reduce(func_name, sequence[, initial])
    • 连续处理
  • map()函数:
    • map(func_name, sequence[, sequence, ...])
    • 待处理序列可以有多个,对应传入的func参数也要有多个;如果长度不一致,短序列后面会补None;
    • 映射
apply(login,('name','pwd'))

def validate(item):
  return True
filter(validate, ('A','B','C'))

filter(lambda n:n%2=0, [1,2,3,4,5,6,7])

def operat(x, y):
  return x*y
reduce(operat, (7,8,9), 5) # 5 * 7 * 8 * 9

def add3(a,b,c):
  return a+b+c
map(add3,[1,2,3],[2,3,4],[3,4,5])

第5章 数据结构

列表(List):

  • append(value)
  • 可遍历
  • insert(index, value)
  • list[index] = value
  • remove(value) 移除列表中指定值的第一个匹配值,如果值不存在会抛异常
  • del list[index]
  • 分片操作:list[m:n],切片也支持切片赋值(左闭右开);
  • 最尾端元素索引为-1;
  • 列表1扩展:list1.extend(list2)
  • 两个列表拼接:list1 + list2list1 * 2
  • list.index(value) 返回索引
  • value in list 判断值是否在列表中
  • 排序:list.sort(reverse=True) list变化不返回值
  • 反转:list.reverse() list变化不返回值

实现堆栈:

  • append() 和 pop()
  • pop() 移除列表元素(默认最后一项),并返回;
  • pop(0) 移除第一项,并返回;
  • pop是唯一一个既能修改列表又能返回值的列表操作方法;

不可变序列——元组

tuple_name = (el1,) 这里的逗号不可省略

  • 添加:tuple_new = (*tuple_pld, el1, el2) 这里使用*可以实现元组的自动解包
  • 访问:tuple[0],注意元组不可修改
  • 解包:a,b,c = tuple(1,2,3)

range函数:range([start, ] stop [, step])

  • start 默认为0
  • stop 必需
  • step 步长,每次递增或递减的值,默认为1

元组和列表都是序列,都可以使用len()计算长度,使用map()映射,使用循环遍历;

字典

字典 是 Pyhton中唯一的内建 映射类型(mapping),Key可以是数字,字符串,元组;

  • {key1:value1, key2:value2},键唯一,值不唯一
  • 赋值和添加:dict[key] = value
  • 删除: del dict[key]del( dict[key] )
  • pop:pop(key [, default_value]),key存在时删除key,不存在则返回默认值
# 使用dict创建字典
dict([(1,'a'), (2,'b'), (3,'a')])

dict(name='A', age=24)


# 字典遍历
for key in dict:
  pass

for (key,value) in dict.items():
  pass

for key in dict.keys():
  pass

for value in dict.values():
  pass    

for (key,value) in dict.iteritems():
  pass

for key in dict.iterkeys():
  pass

for value in dict.itervalues():
  pass    

字典的方法:

  • clear() 清除字典所有项,无返回值
  • copy() 复制一个新字典
  • fromkeys() 使用戈丁的键序列建立新的字典,值默认为None;
    • dict.fromkeys([key1, key2, ...], (default_value))
  • get()dict.get(key [, default_value]),如果key不存在,返回默认值None,且不会报错;
  • has_key() 检查是否包含指定key
  • popitem() 弹出随机元素,字典空时会报错;
  • update() 利用一个字典2更新另一个字典1,dict1.update(dict2)

序列

列表、元组、字符串 都是序列,序列主要两个特点:索引操作符 和 切片;

  • 切片支持步长:nums[0:10:2]
  • 检测元素:if 元素 in 序列
  • 字典排序:
    • key排序:sorted(dict.items(), key=lambda d:d[0])
    • value排序:sorted(dict.items(), key=lambda d:d[1])
    • 排序结果是一个键值对元组的列表;

使用count()方法可以统计元素个数;


第6章 字符串与正则表达式

字符串格式化:

  • 普通方式:print ("我叫 %s 今年 %d 岁!" % ('小明', 10))
  • f-string 是 python3.6 之后版本添加的,称之为字面量格式化字符串,是新的格式化字符串的语法;
  • f'Hello {name}' # 替换变量

字符串方法:

  • '-'.join(['a','b','c'])
  • 'abc'.split('-')
  • strip()lstrip()rstrip()
    • 支持传入一个参数,指定要去除的字符,没传的话,默认会去掉首尾空格;
strs = 'saoaay yes no yaa0aass'
strs.strip('say') # 去除收尾依次在[s ,a, y]数组内的字符
# 'oaay yes no yaa0'

字符串方法:

  • startswith() 判断字符串是否以某一子串开始
    • str.startswith('zcn', 2,5) 带比较字符串 开始比较的位置 和结束比较的位置
  • endswith() 判断字符串是否以某一子串结尾
  • find() 查找字符串子串 返回下标,子串不存在则返回-1
    • str.find(substr [, start [, end]])
  • rfind() 从右边开始查询
  • replace()
    • str.replace(substring, newsubstring, [, max]) max表示替换的次数;

转换时间字符串方法:

  • strptime()
  • strftime()
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import time  # 引入time模块
 
ticks = time.time()
print "当前时间戳为:", ticks


#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import time
 
struct_time = time.strptime("30 Nov 00", "%d %b %y")
print "返回的元组: %s " % struct_time


#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 通过导入 __future__ 包来兼容 Python3.x print
from datetime import datetime

now = datetime.now() # current date and time

year = now.strftime("%Y")
print("year:", year)

month = now.strftime("%m")
print("month:", month)

day = now.strftime("%d")
print("day:", day)

time = now.strftime("%H:%M:%S")
print("time:", time)

date_time = now.strftime("%Y-%m-%d, %H:%M:%S")
print("date and time:",date_time)

正则表达式简介

常用特殊字符:

字符描述
^表示匹配的字符必须在最前边
$匹配最末的字符
*匹配前面字符0次或n次
+匹配前面字符1次或n次
?匹配前面字符0次或1次
.匹配除换行符外的所有字符
(x)匹配x并记录匹配的值
x|y匹配x或者y
{n}匹配前面的n个字符;n是一个正整数
{n,}匹配至少前面的n个字符
{n,m}匹配至少n个 最多m个前面的字符
[xyz]匹配列表中的任一字符;支持通过连字符-指定字符范围
[b]匹配一个空格
b匹配一个单词的分界线;比如一个空格
B匹配一个单词的非分界线

注意 ^[^m],两处^的意义不同;

正则表达式的使用

re模块:

  • compile() 把正则表达式 编译成一个正则表达式对象
  • match() 匹配一个模式
  • search() 查找第一个匹配并返回,否则返回None
  • sub() 替换字符串的匹配项
  • split() 分割字符串
  • findall() 获取所有匹配的字符串

re模块匹配规则:

  • re.I 使匹配对大小写不敏感
  • re.L 做本地化识别(locale-aware)匹配
  • re.M 多行匹配,影响 ^ 和 $
  • re.S 使 . 匹配包括换行在内的所有字符
  • re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B
  • re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解;
  • re.DOTALL 匹配一些特殊标记 例如使用.匹配\n等字符;
import re
text = "welcome+the+conentct+window"
print(re.split(r'\+',text))
# ['welcome', 'the', 'conentct', 'window']
import re

originstr = 'http://upos-sz-mirrorhw.bilivideo.com/upgcxcode/95/97/25aa6429795/256429795-1-32.flv?e=ig8euxZM2rNcNbN37zUVhoMgnwuBhwdEto8g5X10ugNcXBlqNxHxNEVE5XREto8KqJZHUa6m5J0SqE85tZvEuENvNo8g2ENvNo8i8o859r1qXg8xNEVE5XREto8GuFGv2U7SuxI72X6fTr859r1qXg8gNEVE5XREto8z5JZC2X2gkX5L5F1eTX1jkXlsTXHeux_f2o859IB_&uipk=5&nbs=1&deadline=1605519071&gen=playurl&os=hwbv&oi=737348678&trid=6dc40e32c716403881b67bf67f596472u&platform=pc&upsig=1a8747c29f3fbebd9754e8517eb2107c&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,platform&mid=0&orderid=0,3&agrr=1&logo=80000000'
# 匹配以/开头 以?结尾(由于两者是特殊标记 需要进行转义)的字符 且其中不包含/
bstr = r'\/([^\/]*)\?' 
b = re.compile(bstr ,  re.DOTALL)
str_list = b.findall(originstr)
print(str_list) 
# ['256429795-1-32.flv']
bstr = r"""
  ^(?<recordType>[\w]{3,3})(?<senderType>[\w]{2,2})(?<senderId>\d{9,9})(?<senderName>[\x00-\xFF]{45,45})(?<ediStandard>[\x00-\xFF]{5,5})(?<creationDateTime>\d{14,14})(?<transmissionDate>\d{8,8})(?<characterSet>[\w\s]{0,15})"""

b = re.compile(bstr ,  re.DOTALL)
str_list = b.match(content_str)

if str_list:
    linebits = str_list.groupdict()    
    for k, v in linebits.items() :
        # 去除解析之后的字符串的首尾空格
        linebits[k] = v.strip()
    return linebits

第7章 面向对象编程

封装 继承 多态;Python类的属性 方法及特性;

  • 多态:不同类的对象使用相同操作;
  • 封装:对外部隐藏对象工作细节
  • 继承:以类为基础建立专门的类对象
class MyClass(SuperClass):
  # 类属性(也可被实例调用)
  propertyA = ''

  # 静态方法
  @staticmethod
  def methodB():
    pass

  # 类方法
  @classmethod
  def methodD(cls, selfcls):
    pass

  # 构造方法
  def __init__ (self):
    # SuperClass.__init__(self)
    # or 使用super调用父类方法
    super(MyClass, self).__init__(self)
    # 实例属性
    self.propertyB = ''
    # 私有实例属性
    self.__propertyC = ''
    pass

  # 实例方法
  def methodA(self):
    pass
  # 私有实例方法
  def __methodC(self):
    pass

MyClass.propertyA
MyClass().propertyA
MyClass().propertyB
MyClass()._MyClass__propertyC

  • MyClass.bases 输出基类组成的元组
  • myClass.dict 输出属性组成的字典
  • myClass.module 输出类所在模块名
  • myClass.doc 输出doc文档
  • myClass.class 输出类
  • MyClass.name 输出类名

Python会自动绑定类方法的第一个参数,类方法的第一个参数(通常建议参数名为 cls)会自动绑定到类本身;但对于静态方法则不会自动绑定

内置方法:

  • __init__(self, ...) 初始化对象,在创建新对象之前声明
  • __del__(self) 释放对象,在对象被删除之前调用
  • __str__(self) 在使用print语句时被调用
  • __len__(self) 在调用内联函数len()时调用
  • __getarr__(s, name) 获取属性的值
  • __setarr__(s, name) 设置属性的值
  • __delarr__(s, name) 删除name属性
  • __call__(self, *args) 把实例对象作为函数调用

方法的动态特性:

  • Python语言是一种完全面向对象的动态语言,作为动态语言的脚本,用其编写的程序也具有很强的动态特性;主要体现在:可以动态添加类的实例方法;动态添加实例的属性;

类的命名空间

Python中,所有位于class语句中的代码都在特殊的命名空间中执行,该命名空间被称为类命名空间;

class MyNamespace:
  count = 1
  def myinit(self):
    MyNamespace.count += 1

if __name__ == "__main__":
  mynamespace = MyNamespace()
  mynamespace.myinit()
  print(MyNamespace.count)

  • issubclass()函数,可以判断一个类是否是另一个类的子类,issubclass(subclass, superclass)
  • isinstance()函数,可以判断一个对象是否是一个类的实例,isinstance(person, Person)

继承自object的类:

class MyLimeter(object):
  __slots__ = 'myname', 'myage', 'myhoppy'

if __name__ == "__main__":
  x = MyLimeter()
  x.myname = ''

__getarr__()__getarrtibute__()

  • __getarr__() 仅当属性不能在实例/类的__dict__中找到时,调用(也就是对未声明的属性才有效);
  • __getarrtibute__() 对每个属性访问时,都调用(对所有属性都有效);

第8章 基于文件的交互

open()函数:

  • 读模式:r
  • 读写模式:w
  • 写模式:a
  • 二进制模式:b(可与其他模式并用)
  • 打开一个文件进行更新(可读可写): +
o = open('./test.txt','w')
o.read() # 读取所有
o.read(16) # 读取16个字符
o.tell()# 查询当前文件中字符的长度
o.readline() # 按行读取
contents = o.readlines() # 读取所有行
o.write("aaa") 
o.writelines(listcontent) # 参数虚伪集合类型
o.close()

os模块 和 os.path模块

import os

  • os.sep 系统特定的路径分隔符,可取代
  • os.name 显示正在使用的平台
  • os.getcwd() 获取当前工作路径
  • os.getenv() 读取环境变量
  • os.putenv() 设置环境变量
  • os.listdir() 返回指定目录下的所有文件和目录名
  • os.remove() 删除一个文件
  • os.system() 运行shell命令
  • os.path.split() 返回路径名和文件名
  • os.path.isfile() 检测路径是否是文件
  • os.path.isdir() 检测路径是不是目录
  • os.path.existe() 检测给定路径是否真正存在
  • os.chdir(dirname) 改变工作目录到dirname
  • os.path.getsize() 获取文件大小
  • os.path.abspath() 获取绝对路径
  • os.path.join(path, name) 链接目录 文件或目录
  • os.path.basename(path) 返回文件名
  • os.path.dirname(path) 返回文件路径

备份 和 恢复

import shutil:一种高层次的文件操作工具;

  • shutil.copyfile(src,dst) 向有权限的路径copy文件,已有文件会被覆盖
  • shutil.move(src,dst) 移动文件
  • shutil.copy(src,dst)
  • shutil.copy2(src,dst)
  • shutil.copytree(src,dst)
import os
# 创建路径
os.mkdir(dir) 
open(os.path.join(dir, 'filename.txt'), "a+"); # 创建文件

import os
# 创建多级目录
os.makedirs(dir/subdir)

open(os.path.join(dir, 'filename1.txt'), "a+");
open(os.path.join(dir/subdir, 'filename2.txt'), "a+");

import os
# 删除空目录
os.rmdir(dir)

import shutil
# 删除非空目录
shutil.rmtree(dir)

# 示例
if k == 1:
  # 路径以时间命名
  times = "d:\\itzcn\\" + time.striftime("%Y-%m-%d", time.localtime())
  # 判断路径是否存在
  if os.path.exists(times) == False:
    os.makedirs(times)
  # 拼接文件名
  files = times + "\mylog.log"
  # 创建/打开文件
  o = open(files, "a+")
  content = raw_input("请输入您需要记录的事情:\n")
  count = 0
  for s in o.readlines():
    # 读取文件 查找特定字符
    li = re.findall("Text",s)
    if len(li) > 0:
      count = count + li.count("Text")
  content = content.replace("Text", 'NewText')
  o.write(content)
  o.close()

os.walk() os.path.walk()

import os

def Remove_dir(top_dir):
    if os.path.exists(top_dir)==False:
        print ('not exists')
        return
    if os.path.isdir(top_dir)==False:
        print ('not a dir')
        return
    for dir_path,subpaths,files in os.walk(top_dir,False):
        for file in files:
            file_path=os.path.join(dir_path,file)
            print ('delete file:%s")' %file_path
            os.remove(file_path)
        print ('delete dir:%s")'%dir_path
        os.rmdir(dir_path)
Remove_dir(r"C:\Users\Administrator\Desktop\shili")

import os

def find_file(arg,dirname,files):
    for file in files:
        file_path=os.path.join(dirname,file)
        if os.path.isfile(file_path):
            print "find file:%s" %file_path
os.path.walk(r"C:\Users\Administrator\Desktop\4",find_file,())


构造可容错的应用程序

异常处理:

  • try catch
  • try finally
  • raise
  • assert

异常也是对象:

  • 所有异常都是基类Exception的成员,继承自基类Exception;且都在内建的exception模块中定义;
try:
  <要执行的代码>
except <异常对象1>, <异常信息标识>:
  todo
except (<异常对象2>,<异常对象3>,...), <异常信息标识>:
  todo

try:
  s = 1/0
except (IndexError, KeyError, ZeroDivisionError), e:
  print(e)
except Exception:
  print("Exception")
else:
  没有异常时执行
finally:
  不管有没有异常都会执行
  一般用来实现一些清理操作

raise NameError "name error" # 指定异常类 及异常信息

自定义异常

自定义异常需继承Exception类,命名规范以Error结尾;

class MyError(Exception):
  def __init__(self, value):
    self.value = value;

  def __str__(self):
    return repr(self.value)

try:
  raise MyError(2 * 2) # 必须手动触发
except MyError, e:
  print(e.value)

断言assert

assert断言失败,会引发 AssertionError异常;语法:assert <条件表达式> , tint_txt;基础用法和if类似;


持久化数据(Persistence)

媒介:关系型数据库,磁盘文件、XML、数据文件等

  • dbhash、anydbm、shelve模块;
  • 数据库连接 及 游标的使用
  • 读写数据
  • SQLite数据库

序列化:将内存对象序列化成流或者将流反序列化为对象;

  • void Serialize(Stream stream, object o)
  • object Deserialize(Stream stream)

序列化解决了对象的传输问题,传输可以在线程 进程 内存 外村 主机间进行;

DB-API规范:

  • 定义一些列必须对象和 数据库存取方式,为多种数据库提供一致的访问接口;
  • MySQL、SQLite

connect

  • 参数:
    • dsn 数据源名称
    • user 连接数据库的用户名
    • password 连接数据库的密码
    • host 主机名
    • database 连接数据库的名称
  • 返回:连接对象

连接对象的方法:

  • close() 关闭连接,连接对象和游标都不能用(未提交的事务 隐式回滚)
  • commit() 该方法 提交挂起的事务
  • rollback() 回滚挂起的事务
  • cursor() 返回一个连接的游标对象 用于执行SQL查询 并检查结果

游标对象的方法:

  • callproc(name [, params]) 使用给定的名称和参数调用已经命名的数据库程序,其中参数可有可无
  • close() 关闭游标
  • execute(oper [, params]) 执行SQL操作 参数可有可无
  • executemany(sql1, sql2) 对每个参数执行SQL操作
  • fetchone() 将查询得到的结果集中的下一行 保存为序列
  • fetchmany([size]) 获取查询结果集的多行
  • fetchall() 获取结果集中的所有行
  • nextset() 跳至下一个可用的结果集
  • setinputsizes(sizes) 为参数预定义一个内存区域
  • setoutputsize(size) 为获取大量数据的值设定缓存区尺寸

游标对象的属性:

  • description 结果列描述的序列,只读
  • rowcount 获得结果集中的行数
  • arraysize:fetchmany中返回的行数,默认为1

持久化模块—— dbhash

DBM 数据库 是一种文件式数据库,采用hash结构存储,它不具备管理能力,但是比不同文件稳定、可靠、查询速度也更快;

dbhash是window系统实现DBM数据库的模块:

  • open(filename, flag) 数据库名 模式:w r c 读写 只读 创建
  • 仅支持字符串类型的值
import dbhash

db = dbhash.open('tem','c')
db['东'] = "awefawef"
db['西'] = "awefaweawfe"
for k,v in db.iteritems():
  print(k,v)
if db.has_key('东'):
  del db['东']

db.close()

持久化模块—— shelve

使用和dbhash类似,区别是shelve返回的字典类型支持Python中的基本类型,字符串 数字 元组 列表;

注意:字典的key只能是字符串类型;

import shelve
db = shelve.open('mydb') # 不存在 则创建
db['a'] = ['a', 4000]
print(db)
db.close()

持久化模块—— anydbm

与 dbhash用法基本一致;anydbm.open('db.dat', 'c')

SQLite数据库的使用

SQLite是一个开源的嵌入式数据库引擎;

安装数据库管理工具:Navicat Premium

import sqlite3

# host user password database
conn = sqlite3.connect('userDB.db') # 不存在则创建

conn.execute("""
  create table if not exists address(
    id integer primary key autoincrement,
    name varchar(128),
    address varchar(128)
  )
""")

conn.execute("""
  insert into address(name, address) values
    ('hq', 'beijing')
""")

conn.commit()

cur = conn.cursor()
cur.execute("select * from address")
res = cur.fetchall()
print(res)
for line in res:
  for f in line:
    print(f)
cur.close()
conn.close()

Python网络功能

  • TCP/IP网络互联模型
  • Socket
  • 服务器 客户端
  • 异步通信
  • Twisted网络框架

OSI7层网络模型:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层;

TCP/IP:传输控制协议/网络互联协议;通过IP区分子网;通过端口号区分应用;

Socket:使用套接字可以是用户在不同主机之间进行通信,从而实现数据交换;

  • 流套接字:双向有序不重复的数据服务
  • 数据报套接字:虽然也支持啥时能像 但是对报文可靠性和有序性不能保证
  • 客户端套接字:Client 链接 完成事务 断开连接
  • 服务器套接字:Server 随之准备客户端的链接 同时还要处理多个链接
  • 一个套接字就是一个Socket模块中Socket类的实例;

socket(socket_family, socket_type, protocol = 0)

  • 地址簇 socket.AF_INET AF_INET6 或 AF_UNIX
  • 套接字类型 流 socket.SOCK_STREAM 或 数据报 socket.SOCK_DGRAM
  • 使用的协议,默认0

客户端生成套接字对象、调用bind()方法绑定自己请求的套接字接口地址、调用connect()方法链接服务器进程;建立连接后可以使用send()和recv()方法传输数据;最后需要使用close()方法将端口关闭;

服务端套集资使用bind()方法绑定一个套接字接口地址,接着使用listen()方法监听客户端请求;当有客户端请求时,将通过accept()方法来生成一个连接对象,然后通过此连接对象发送和接收数据;数据传输完毕,可调用close()方法关闭连接;

urllib 和 urllib2模块

允许通过网络访问文件;把URL所指向的文件用程序访问;

  • urllib:简单下载
  • urllib2:HTTP验证 或 Cookie、为协议写扩展程序;

urllib2:

  • 是Python的一个获取URL的模块;
  • 打开远程文件:urlopen(url, data=None, proxies=None)
    • url 参数格式key=value 代理服务器地址
import urllib2
# 这里response是一个文件对象 支持 close read readline readlines方法
response = urllib2.urlopen("http://www.baidu.com")
html = response.read()

# 本地文件
urllib2.urlopen("file://c:\\text\\test.txt")

urlretrieve(url, filename=None, reporthook=None, data=None)

  • 下载文件并存储本地,返回的是一个元组(filename, headers)
  • filename 本地文件路径的字符串,如果为None则临时生成一个;
  • reporthook(blockcount blocksize size) 已传递数据块数量、数据块大小、文件总大小;
  • data:参数数据字符串,符合key=value格式;

urlcleanup()方法,可以用来清理临时文件;

标准库中网络相关模块:

  • asynchat/asyncore异步套接字处理程序/cgi/Cookie/cookielib/email/ftplib/gopherlib/httplib/imaplib/mailbox/mailcap/mhlib/nntplib/opolib/robotparser/smtpd/smtplib/telnetlib/urlparse/xmlrpclib

服务器

# server
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5) # 监听5个链接
while True:
  c, addr = s.accept() # 链接对象 链接对端地址
  c.send('something')
  c.close()

SocketServer模块:简化服务器端编程

  • BaseServer
  • TcpServer -> UNIXStreamServer
  • UDPServer -> UNIXDatagramServer

通过对SocketServer模块中类的继承,可以实现更多功能的服务器端应用程序;
BaseHTTPServer、SimpleHTTPServer、CGIHTTPServer、SimpleXMLRPCServer、DocXMLRPCServer等均派生于TCPServer

from SocketServer import TCPServer, StreamRequestHandler

# 每处理一个链接 就会实例化一个handler类
class Handler(StreamRequestHandler):
  # 重载handle方法
  def handle(self):
    # 获取链接 对端地址
    add = self.request.getpeername() 
    # request client_address server 属性
    self.wfile.write('something')

# 生成TCP服务器
server = TCPServer(('',1234), Handler)
# 开始监听 并处理链接
server.serve_forever()

自定义的链接处理类,还可以重载setup()、finish()方法;前者做一些初始化,后者则进行一些清理操作;

客户端

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port=1234
s.connect((host, port))

s.recv(1024)
s.close()

异步通信

之前介绍的都是同步实现;如果需要服务器端能够同时处理多个链接,则需要使用异步通信方式;

Python标准库的3中处理:

  • 分叉 ForkingMixIn
  • 线程 ThreadingMixIn
  • 异步I/O asynchronous I/O

分叉处理:

  • 每接收到一个链接,主线程都会生成相应的一个子进程专门用来处理此链接;
  • 主进程依然保持侦听状态
  • 缺点是:生成进程消耗较大;分叉基本就意味着复制进程
from SocketServer import TCPServer, ForkingMixIn, StreamRequestHandler

class Server(ForkingMinIn, TCPServer):
  pass

class Handler(SteamRequestHandler):
  def handle(self):
    addr = self.request.getpeername()
    self.wfile.write('something')
  
if __name__ == '__main__':
  server = Server(('localhost', 1234), Handler)
  server.serve_forever()

线程方式:

  • 收到链接时,主线程将生成子线程来处理连接,主线程继续处于侦听状态
from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler

class Server(ThreadingMixIn, TCPServer):
  pass

异步I/O:

  • 由asyncore和asynchat模块提供支持,依赖select模块的select()和poll()方法;
  • select() 用于对指定的文件描述符进行监视,在文件描述符改变时做出响应
import socket, select

s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)

inputs = [s]
while True:
  rs,ws,es = select.select(inputs, [], [])
  for r in rs:
    if r is s:
      c, addr = s.accept()
      inputs.append(c)
    else:
      try:
        data = r.recv(1024)
        disconnected = not data
      except socket.error:
        disconnected = True
      if disconnected:
        inputs.remove(r)
      else:
        print(data)

asyncore模块

使用聊天类的服务器和协议实现,常见多个信道,调用loop(0方法来激活信道;)

Twisted

是一个面向对象给予事件驱动的顶级通信框架,允许使用和开发完全异步的网络应用;


第12章 HTML处理

  • URL字符串的处理
  • CGI环境配置

URL:

  • 协议://授权(服务器名或IP地址:端口号)/路径?查询

常用协议:

  • http 超文本传输协议
  • https 使用安全套阶层的超文本传输协议
  • ftp 文件传输协议
  • file 本地主机文件
  • telnet Telnet协议

解析url:

import urlparse

url = urlparse.urlparse('https://www.baidu.com/search?pid=5')
url.scheme
url.netloc
url.path
url.params
url.query
url.fragment
url.hostname
url.port

CGI:公共网关接口,是外部应用程序和 HTTP服务器之间交互的一个通用接口标准;


GUI

  • TKinter,基于TKinter扩展的pmw、Tix
  • wxWidget,boa constructor

wxPython

  • import wx
  • wxPython的开发工具: WxGlade、WxFormBuilder、Boa-constructor;

Django

Django拥有完善的模板机制,对象关系映射机制以及用于动态创建后台管理界面的功能;


常用库

  • import random
  • from decimal import Decimal
  • import re
  • import os
  • import shutil

总结

由于本书发行过早,书中实践部分的内容,仅浏览,当下许多内容已有变化;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值