简介
- 易学
- 跨平台
- 胶水
- 语法有趣
测试框架:selunium (web)、robotfarmework(将表格翻译成脚本)、pyunit(单元测试)
数据类型


1、整数: 0,1,-9,十六进制:0x12ad
2、浮点数: 1.23e-3 = 1.23*10^(-3)
3、字符串: 单引号或双引号
4、转义字符: \n换行 \t制表符 r' '表示引号内部的字符默认不转义'''内部的可以多次回车显示'''
5、布尔值: true 或是false,可以和and or not进行运算
6、空值: None
变量和常量: python是动态语言,默认用大写字母表示常量,但是常量并不是不可变的。
7、字符类型str
编码: 字符编码—unicode编码—utf-8编码
`ord(“A”)` :将单个字符A转变为整数表示
`chr(“383”)` :将整数转变为对应的字符
str转换成为byte:
’str’.encode(‘ascii’)
byte转换成为str: b’abc’.decode(‘ascii’)
中文超过了str和byte的范围,不能使用 decode
str的长度: len(’abc’)
字符串是不可变对象
>>> a = 'abc'
>>> b = a.replace('a', 'A')
>>>a.replace('a','A')
'Abc'
>>> b
'Abc'
>>> a
'abc'
Python
#开头
#!usr/bin/env/python3 这是一个python程序
# -*- coding:utf-8 -*- 按照utf-8编码
字符串格式化:
整数 `d% `
浮点 `f%`
字符串 `s%`
十六进制 `x%`
format():
'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%’
列表list
Class = [‘aa’,’bb’,’kk’]
长度len(class): 3
索引class[0]:’aa’ class[-1]:’kk’
追加元素到末尾 : class.append(‘value')
追加元素到指定位置:class.insert(2,’value’)
删除末尾元素:calss.pop()
删除指定位置:class.pop(i)
排序 :class.sort()
元组touple()
——元组可读不可变
num = (1,2,3,4)
长度len(num):4
索引num(0) :1
注意: 当元组中只有一个数据时,要加逗号
t = (1,)
t = (1) : 1 和数学公式中的()产生歧义,最后python取的是数学中的数字
字典dict{key:value}
初始化: dict = {"kk":98,"talor":100,"vae":99}
取数据:dict["kk"]或者dict.get("vae")
若key不存在会报错
判断key是否存在:
'kk' in dicttrue /false
dict.get('mm')None
存/修改数据:dict["kiky"] = 88 后面的数据会冲掉之前的数据,即修改
删数据:dict.pop("kiky")
注意:
---和列表相比,随着数据的增多,占用的内存空间:字典>列表,需要的时间:字典<列表
---字典dict中的key必须不可变,正常字符串为不可变变量,可以放心使用。
---python为字典dict,其他语言为map
set集合
set也是字典,只包含了key值,不包含value值。
set 集合可以认为是数学上,不重复/无顺序的集合
添加:se.add(4) ----重复添加相同的,不会有效果。
添加:se.update(x):x可以是列表、元组、字典等。
删除:se.remove(4)不存在会发生错误
删除:se.discard(4)不存在不会发生错误
交集:&
并集:|
不同时存在的值: ^
se = set([1,2,3])
se
{1,2,3}
条件判断:
if 条件1:
pass
elif 条件2:
pass
elif 条件3:
pass
else :
pass
while else结构,在条件语句为 false 时执行 else 的语句块
while a==1 :
pass
while a<5:
a +=1
else
print(a大于等于5)
循环
for x in [1,2,3,4,5]:
for x in range(5): range(5):0—4,即0,1,2,3,4
While 满足条件就一直执行
break:结束当前循环
continue:结束本轮循环,直接进入下一轮循环
函数
- 空函数
def kong():
pass //占位符,让程序可以运行起来
- 参数错误
调用函数时,会检查参数的个数。 - 返回多个值
return x,y //其实返回的是一个元组。
必选参数x,n
def power(x,n)
默认参数n=2
def power(x,n=2)
pass
power(3) //只需要提供一个参数
def add_end(L=[]):
L.append('END')
return L
>>> add_end()
['END']
>>> add_end()
['END', 'END']
'--------注意:默认参数必须指向不可变变量-----------'
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
可变参数
'元组' 或'列表'作为位置参数进行传递
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
>>> calc([1, 2, 3])
14
'--------------变为可变参数---------加*'
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
>>> calc(1, 2)
5
>>> nums = [1, 2, 3]
>>> calc(*nums)
14
关键字参数
'字典'作为位置参数进行传递 '**'
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
命名关键字参数
位置参数和命名关键字参数中间必须加'*'间隔开,否则都是必选参数
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不需要一个分隔符*
def person(name, age, *, city, job):
print(name, age, city, job)
调用时,必须加上参数名
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer
参数组合
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数这5种参数组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
- 递归函数
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
- range函数
for i in range(5):0,1,2,3,4
for i in range(5,9) :5,6,7,8
for i in range(0, 10, 3) :0,3,6,9
>>>a = ['Google', 'Baidu', 'Runoob', 'Taobao', 'QQ']
>>> for i in range(len(a)):
... print(i, a[i])
0 Google
1 Baidu
2 Runoob
3 Taobao
4 QQ
高级特性
切片
元组/列表取值
>>> L[0:3] '不包括L[3]'
[L[0], L[1], L[2]]
>>> L[-2:] '默认包括倒数第一个,所以是倒数第一个和倒数第二个'
[L[-2],L[-1]]
>>> L[-2:-1] '不包括倒数第一个'
[L[-2]]
>>> L[:10:2] '前10个数,每两个取一个'
[0, 2, 4, 6, 8]
迭代--可迭代对象for in
- 字典
默认情况下,dict迭代的是key。
如果要迭代value,可以用'for value ind.values()'
如果要同时迭代key和value,可以用'for k, v in d.items()'。
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> for key in d:
... print(key)
...
a
c
b
- 字符串
>>> for ch in 'ABC':
... print(ch)
...
A
B
C
判断是否可迭代
>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False
- 列表生成式
- 生成器
- 迭代器
python 高级教程
正则表达式 import re
re.metch(r,str,med) #从str的开头开始匹配
re.search(r,str,med) #匹配整个str,直到找到匹配
re.sub()
re.findall
re.finditer
re.split(r,str,0/1) #分隔全部或一次
group
CGI编程 通用网关接口
MySQL
- 原子性:不可分割,要么都做,要么都不做
- 一致性:从一个一致性状态转变到另一个一致性状态
- 持久性:事务一旦提交,对数据库的改变应该是永久性的
- 隔离性:一个事务的执行不能被其他事务干扰
python -m pip install mysql-connector #安装
import mysql.connertor #导入模块
mydb = mysql.connector.connect(host='localhost',
user='username',passwd='password') #创建连接
mycursor = mydb.cursor() #创建游标对象
mycursor.excute("CRATE DATABASE run-db") #执行创建数据库
MySQL
显示数据库
show databases
创建数据表
creat table xxx(row1 varchar(255),row2 varchar(255))
show tables
修改表
alter table xxx add column xxx int auto_increment primary key #修改表添加列
插入数据
inter into xxx (row1,row2) values (key1,key2)
占位符插入数据
sql = "inter into xxx (row1,row2) values (%s,%s)"
val = ("row1key",row2key)
mycursor.excute(sql,val)
mydb.commit() #数据表内容更新
批量插入
sql = "INSERT INTO sites (name, url) VALUES (%s, %s)"
val = [
('Google', 'https://www.google.com'),
('Github', 'https://www.github.com'),
('Taobao', 'https://www.taobao.com'),
('stackoverflow', 'https://www.stackoverflow.com/')
]
mycursor.executemany(sql, val)
mydb.commit() # 数据表内容有更新,必须使用到该语句
数据查询所有fetchall
mycursor.execute("SELECT * FROM sites")
myresult = mycursor.fetchall() # fetchall() 获取所有记录
for x in myresult:
print(x)
数据查询获取一条
mycursor.execute("SELECT * FROM sites")
myresult = mycursor.fetchone() #获取一条数据
print(myresult)
where条件语句
sql = "SELECT * FROM sites WHERE name ='RUNOOB'"
mycursor.execute(sql)
myresult = mycursor.fetchall()
for x in myresult:
print(x)
通配符%
sql = "SELECT * FROM sites WHERE url LIKE '%oo%'"
排序 order by
sql = "SELECT * FROM sites ORDER BY name" #默认升序asc,降序desc
limit
mycursor.execute("SELECT * FROM sites LIMIT 3")
offset设置起始位置
mycursor.execute("SELECT * FROM sites LIMIT 3 OFFSET 1") # offset 0 为 第一条,1 为第二条,以此类推
删除记录
sql = "DELETE FROM sites WHERE name = 'stackoverflow'"
mycursor.execute(sql)
mydb.commit()
更新数据
sql = "UPDATE sites SET name = 'ZH' WHERE name = 'Zhihu'"
mycursor.execute(sql)
mydb.commit()
删除表
sql = "DROP TABLE IF EXISTS sites" # 删除数据表 sites
mycursor.execute(sql)
PyMySql
#!/usr/bin/python3
import pymysql
# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
# 使用 execute() 方法执行 SQL 查询
cursor.execute("SELECT VERSION()")
# 使用 fetchone() 方法获取单条数据.
data = cursor.fetchone()
print ("Database version : %s " % data)
# 使用 execute() 方法执行 SQL,如果表存在则删除
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")
# 使用预处理语句创建表
sql = """CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )"""
cursor.execute(sql)
# SQL 插入语句
sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
except:
# 如果发生错误则回滚
db.rollback()
# SQL 查询语句
sql = "SELECT * FROM EMPLOYEE \
WHERE INCOME > %s" % (1000)
try:
# 执行SQL语句
cursor.execute(sql)
# 获取所有记录列表
results = cursor.fetchall()
for row in results:
fname = row[0]
lname = row[1]
age = row[2]
sex = row[3]
income = row[4]
# 打印结果
print ("fname=%s,lname=%s,age=%s,sex=%s,income=%s" % \
(fname, lname, age, sex, income ))
except:
print ("Error: unable to fetch data")
# SQL 更新语句
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M')
try:
# 执行SQL语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
except:
# 发生错误时回滚
db.rollback()
# SQL 删除语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)
try:
# 执行SQL语句
cursor.execute(sql)
# 提交修改
db.commit()
except:
# 发生错误时回滚
db.rollback()
# 关闭数据库连接
db.close()
Python3网络编程
Python 提供了两个级别访问的网络服务。:
- 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。
- 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。
socket又称套接字,应用程序通过套接字向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
| 服务器端套接字 | 详解 |
|---|---|
| s.bind() | 绑定地址(host,port) |
| s.listen() | 开始TCP监听 |
| s.accept() | 被动接受TCP客户端连接,阻塞式等待连接的到来 |
| 服务器端套接字 | 详解 |
|---|---|
| s.connect() | 主动初始化TCP服务器连接,一般address的格式为(host,port),如果连接出错,返回socket.error |
| s.connect_ex() | connect函数的扩展版本,出错时返回出错码,而不是抛出异常 |
| 公共用途的套接字 | 详解 |
|---|---|
| s.recv() | 接受TCP数据,数据以字符串形式返回 |
| s.send() | 发送TCP数据,返回值是要发送的字节数 |
| s.sendall() | 完整发送TCP数据,成功返回none,失败抛出异常 |
| s.recvfrom | 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址 |
| s.sendto() | 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 |
| s.close() | 关闭套接字 |
| s.getpeername() | 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port) |
| s.getsockname() | 返回套接字自己的地址。通常是一个元组(ipaddr,port) |
| s.setsockopt(level,optname,value) | 设置给定套接字选项的值 |
| s.getsockopt(level,optname[.buflen]) | 返回套接字选项的值 |
| s.settimeout(timeout) | 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) |
| s.gettimeout() | 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 |
| s.fileno() | 返回套接字的文件描述符 |
| s.setblocking(flag) | 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常 |
| s.makefile() | 创建一个与该套接字相关连的文件 |
服务端
#!/usr/bin/python3
# 文件名:server.py
# 导入 socket、sys 模块
import socket
import sys
# 创建 socket 对象
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
# 套接字家族可以使AF_UNIX或者AF_INET
#套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM
#protocol: 一般不填默认为0.
# 获取本地主机名
host = socket.gethostname()
port = 9999
# 绑定端口号
serversocket.bind((host, port))
# 设置最大连接数,超过后排队
serversocket.listen(5)
while True:
# 建立客户端连接
clientsocket,addr = serversocket.accept()
print("连接地址: %s" % str(addr))
msg='欢迎访问菜鸟教程!'+ "\r\n"
clientsocket.send(msg.encode('utf-8'))
clientsocket.close()
客户端
#!/usr/bin/python3
# 文件名:client.py
# 导入 socket、sys 模块
import socket
import sys
# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取本地主机名
host = socket.gethostname()
# 设置端口号
port = 9999
# 连接服务,指定主机和端口
s.connect((host, port))
# 接收小于 1024 字节的数据
msg = s.recv(1024)
s.close()
print (msg.decode('utf-8'))
Python internet模块
| 协议 | 功能 | 端口 | 模块 |
|---|---|---|---|
| http | 网页访问 | 80 | httplib,urllib,xmlrpclib |
| nntp | 阅读和张贴新闻文章 | 119 | nntplib |
| ftp | 文件传输 | 20 | ftplib,urllib |
| SMTP | 发送邮件 | 25 | smtplib |
| pop3 | 接受邮件 | 110 | poplib |
| IMAP4 | 获取邮件 | 143 | imaplib |
| Telnet | 命令行 | 23 | telnetlib |
| gopher | 信息查找 | 70 | gopherlib,urllib |
smtp发送邮件
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
from email.header import Header
sender = 'from@runoob.com'
receivers = ['429240967@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')
message['From'] = Header("菜鸟教程", 'utf-8') # 发送者
message['To'] = Header("测试", 'utf-8') # 接收者
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, message.as_string())
print ("邮件发送成功")
except smtplib.SMTPException:
print ("Error: 无法发送邮件")
如果我们本机没有 sendmail 访问,也可以使用其他服务商的 SMTP 访问(QQ、网易、Google等)
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# 第三方 SMTP 服务
mail_host="smtp.XXX.com" #设置服务器
mail_user="XXXX" #用户名
mail_pass="XXXXXX" #口令
sender = 'from@runoob.com'
receivers = ['429240967@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')
message['From'] = Header("菜鸟教程", 'utf-8')
message['To'] = Header("测试", 'utf-8')
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP()
smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号
smtpObj.login(mail_user,mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
print ("邮件发送成功")
except smtplib.SMTPException:
print ("Error: 无法发送邮件")
Python脚本
#! /usr/bin/env python3//在脚本开头加上此句
chmod +x hello.py
./hello.py
end 关键字:print(b,end = ',')