0,python运行与调试
1)命令行参数
python test.py arg1 arg2 arg3
- sys.argv 是命令行参数列表。
- len(sys.argv) 是命令行参数个数。
2)pdb调试
import pdb
pdb.set_trace() #运行到此处为止,当前显示行为下一次执行的行(还未执行)
常用快捷键:
n next 执行下一行
c continue 跳到下一个pdb.set_trace() 处,没有则直接结束
变量名 查看变量值
exit 退出
shell运行:
python3 -m pdb test.py
3)Pycharm远程调试
4)环境变量
1>PYTHONPATH
PYTHONPATH:Linux系统环境变量,主要作用:python查找模块、包的路径时,每导入一个模块,python解释器将依次在PYTHONPATH下寻找。通过sys.path可以查看PYTHONPATH的具体内容。
如果PYTHONPATH被污染,重置方式:unset PYTHONPATH
1,特殊规定
- 缩进:没有{},通过缩进控制模块范围。所有缩进一致即可,一般采用4个空格
- 多行分隔符:斜杠( \),将一行代码分多行显示。语句中包含 [], {} 或 () 括号就不需要使用多行连接符。
total = item_one + \
item_two + \
item_three
- 引号:使用引号( ’ )、双引号( " )、三引号( ‘’’ 或 “”" ) 来表示字符串。其中三引号可以由多行组成,编写多行文本的快捷语法,常用于文档字符串,在文件的特定地点,被当做注释。
paragraph = """这是一个段落。
包含了多个语句"""
- 注释:
#号开头或者使用三个单引号(‘’')或三个双引号(“”")进行多行注释。
'''
这是多行注释,使用单引号。
这是多行注释,使用单引号。
'''
"""
这是多行注释,使用双引号。
这是多行注释,使用双引号。
"""
2,中文编码
1)Python2
Python2中默认的编码格式是 ASCII 格式,在没修改编码格式时无法正确打印汉字。
# -*- coding:utf-8 -*-
logger.info(u"输入:")
li = [((33, 39), '宝马'), ((36, 39), '马')]
print str(li).decode('string_escape')
2)Python3.X
Python3.X 源码文件默认使用utf-8编码,所以可以正常解析中文,无需指定 UTF-8 编码。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# windows是gbk编码 这样输出中文
s1=u'哈'
3)unicode编码解码
对于很多Unicode编码(\u4eba,或者u'中文‘),需要进行转码为utf-8,针对不同场景需要以下三种方法:
s = r'\u4eba\u751f\u82e6\u77ed\uff0cpy\u662f\u5cb8'
s = s.decode('unicode_escape')
default_encoding = 'utf-8'
import os
str(dict).decode('string-escape')
对于从数据库查出来的jsonb对象,可能为Unicode编码,需要进行json转换。
3,输入输出
1)输入
raw_input
从标准输入读取一个行,并返回一个字符串(去掉结尾的换行符):
username = raw_input("请输入账户:")
input
与raw_input类似,但是input 可以接收一个Python表达式作为输入,并将运算结果返回。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
str = input("请输入:")
print "你输入的内容是: ", str
结果:
请输入:[x*5 for x in range(2,10,2)]
你输入的内容是: [10, 20, 30, 40]
密文输入
# Author:dancheng
//导入密码密文文件
import getpass
password = getpass.getpass("password:");
print(password)
2)输出:print
counter = 100 # 赋值整型变量
print ("Hello, Python!")
print counter
3)File 对象方法
file 对象提供了操作文件的一系列方法:
1>读
#读取指定行数
def file_read(line_target):#传入的参数为要获取文本的目标行数
list=[] # 存档列表
with open ('1.txt','r',encoding='utf-8') as file:
for num, line in enumerate(file): # num从0开始循环,所以对应的行数要减一
line = line.strip('\n') # 删除换行符
if num == line_target - 1: # 当行数循环到等于传入的参数值减一时,返回这一行的文本内容并跳出循环
list.append(line)
return list
break
#读取所有行
SaveList = [] # 存档列表
# 读取文本内容到列表
with open("1.txt", "r", encoding='utf-8') as file:
for line in file:
line = line.strip('\n') # 删除换行符
SaveList.append(line)
file.close()
2>写
# 按列输出 每一行2列
with open("text.txt","w",encoding='utf-8') as file:
for i,j in zip(file_read(1)[0].split(),file_read(2)[0].split()):#此处修改为你自己的行数file_read(1),或者添加行
file.write(str(i)+' '+str(j)+'\n')
file.close()
| 文件模式 | 说明 | 文件不存在 | 覆盖or append | 备注 |
|---|---|---|---|---|
| r | 读 | - | - | 默认文件访问模式 |
| r+ | 读+写 | 报错 | 覆盖 | |
| w+ | 读+写 | 创建 | 覆盖 | close之后才算完成写入 |
| w | 写 | 创建 | 覆盖 | |
| a | 写 | 创建 | append内容 | |
| a+ | 读+写 | 创建 | append内容 | |
| r+ | 读+写 | 报错 | 先读后写是append,直接写是覆盖 |
| 说明 | 方法 | 备注 |
|---|---|---|
| 打开文件 | fo = open("foo.txt", "w") | |
| 文件名 | fo.name | |
| 是否已关闭 | fo.closed | |
| 访问模式 | fo.mode | |
| 末尾是否强制加空格 | fo.softspace | 如果用print输出后,必须跟一个空格符,则返回false。否则返回true |
| 关闭文件 | fo.close() | 刷新缓冲区里还没写入的信息,close之后不可写入。如果fo被指定给另一个文件时,Python 会关闭之前的文件。 |
| 读文件 | fo.read(10) | 无参数表示读取所有;有参数表示读n个字符 |
| 写文件 | fo.write( “abc\n”) | 不会在字符串的结尾添加换行符(‘\n’) |
| 文件定位 | fo.tell() | 下一次的读写会发生在文件开头这么多字节之后 |
| 指针指向指定的文件位置 | seek(offset [,from]) | Offset:要移动的字节数; From:开始移动字节的参考位置。 把指针再次重新定位到文件开头: fo.seek(0, 0) |
4)OS 对象方法
提供了处理文件及目录的一系列方法。
import os
| 方法 | 说明 | 举例 |
|---|---|---|
| os.system(cmd) | 运行shell命令cmd | 可以用于执行shell脚本 |
| os.rename( “test1.txt”, “test2.txt” ) | 重命名文件test1.txt到test2.txt | |
| os.remove(“test2.txt”) | 删除一个已经存在的文件test2.txt | |
| os.mkdir(“test”) | 创建目录test | |
| os.chdir(“/home/newdir”) | 将当前目录改为"/home/newdir" | |
| os.rmdir( “/tmp/test” ) | 删除”/tmp/test”目录 | 只能删除空目录,要删除目录及文件用shutil.rmtree( src ) |
| os.path.exists(test_file) | 检验文件、路径是否存在 | test_file可以是文件或路径,是则返回True |
| os.getcwd() | 获取当前工作目录路径 | |
| os.path.abspath(‘.’) | 获取当前工作目录路径 | |
| os.path.abspath(‘test.txt’) | 获取当前目录文件下的工作目录路径 | |
| os.path.abspath(‘…’) | 获取当前工作的父目录 !注意是父目录路径 | |
| os.path.abspath(os.curdir) | 获取当前工作目录路 | |
| sys.argv[0] | 本地路径 | 需要import sys |
os.path.dirname(path) | 获取上一层目录 | parent_dir = os.path.dirname(os.path.dirname(file_path)) 获取上上级目录 |
os.sep | 获取文件目录分隔符 | |
| os.path.basename(filename) | 获取文件名(包含后缀) |
1>os.walk:获取当前目录(包括子目录)下的所有文件
file_list = os.walk(parent_dir,followlinks = "true")
#jmx文件名列表
jmx_file_map = {}
for root, dirs, file_names in file_list:
for file_name in file_names:
print file_name
5)XML读取—ElementTree模块
Python2.5后加入了python标准库。
import xml.etree.ElementTree as ET
1>写
构建
#encoding=utf-8
import xml.etree.ElementTree as ET
#新建xml文件
def buildNewsXmlFile():
#设置一个新节点,并设置其标签为root
root = ET.Element("root")
#在root下新建两个子节点,设置其名称分别为sina和chinabyte
sina = ET.SubElement(root, "sina")
chinabyte = ET.SubElement(root, "chinabyte")
#在sina下新建两个子节点,设置其节点名称分别为number和first
sina_number = ET.SubElement(sina, "number")
sina_number.text = "1"
sina_first = ET.SubElement(sina, "first")
sina_first.text = "http://roll.tech.sina.com.cn/internet_all/index_1.shtml"
#在chinabyte下新建两个子节点,设置其节点名称为number和first
chinabyte_number = ET.SubElement(chinabyte, "number")
chinabyte_number.text = "1"
chinabyte_first = ET.SubElement(chinabyte, "first")
chinabyte_first.text = "http://www.chinabyte.com/more/124566.shtml"
#将节点数信息保存在ElementTree中,并且保存为XML格式文件
tree = ET.ElementTree(root)
tree.write("urlfile.xml")
修改:
for rank in tree.iter('rank')
new_rank = int(rank.text)+1
rank.text = str(new_rank)
rank.set('updated', 'yes')
tree.write(xml_name)
2>读
<?xml version="1.0" encoding="UTF-8"?>
<contry name = "a">
<city>xian</city>
</contry>
<contry name = "ab">
<city>changsha</city>
</contry>
#将XMl文件加载并返回一个ELementTree对象.
#xml_name为文件路径+文件名
tree = ET.parse(xml_name)
#得到第一个匹配contry标签的Element对象
contry= tree.find("contry")
#得到contry的SubElement
for sub_tag in contry:
print sub_tag.text
#得到所有的contry标签
contry_list= tree.findall("contry")
#获取contry标签的name属性
contry.get("name")
#获取标签内容:xian
city.text
4,数据类型
# 获取对象类型
type(object)
Python有五个标准的数据类型:
1)Numbers(数字)
不可改变的数据类型,这意味着改变数字数据类型会分配一个新的对象。
包括4种:int(有符号整型),long(长整型[也可以代表八进制和十六进制],以L结尾),float(浮点型),complex(复数) 。
long 类型只存在于 Python2.X 版本中,在 2.2 以后的版本中,int 类型数据溢出后会自动转为long类型。在 Python3.X 版本中 long 类型被移除,使用 int 替代。
2)String(字符串)
python的字串列表有2种取值顺序:
从左到右索引默认0开始的
从右到左索引默认-1开始的

str = 'Hello World!'
常见字符串运算
| 功能 | 实现 | 备注 | 举例 |
|---|---|---|---|
| 获取子串索引 | str = 'abcd1234dcba' str.index('cd') str.find('cd') | index没有找到引发ValueError;find没有找到返回-1 | 2 |
| 父串包含字串 | if str1 in str2: | 如果包含返回true | |
| 字符串拼接 | join() | str = "-" seq = ("a", "b", "c") str.join(seq) 输出a-b-c | |
| 字符串拼接 | + | str + "TEST" | |
| 字符串截取 | 直接下标拿数据 | str[0] # 字符串中的第一个字符 str[2:5] #字符串中第三个至第六个之间的字符串 str[2:] # 从第三个字符开始的字符串 str * 2 #字符串重复两次 | |
| 字符串是否以某个字符串结尾 | str.endswith('world') | ||
| 字符串替换 | msg.replace('Hello', 'Hi') | ||
| 符串转Byte | string.encode('utf-8') | ||
| Byte转Unicode字符串 | byte = b'Hello, world!' string = byte.decode('utf-8') |
3)List(列表)
语法和字符串一致。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
list = [ 'runoob', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']
print list # 输出完整列表
print list[0] # 输出列表的第一个元素
print list[1:3] # 输出第二个至第三个元素
print list[2:] # 输出从第三个开始至列表末尾的所有元素
print tinylist * 2 # 输出列表两次
print list + tinylist # 打印组合的列表
常用列表函数及方法:
| 函数 | 说明 | 备注 |
|---|---|---|
| len(list) | 列表元素个数 | |
| list.append(obj) | 在列表末尾添加新的对象 | |
| list.remove(obj) | 移除列表中某个值的第一个匹配项 | 注意不要在列表的循环中直接remove,会影响循环 |
| list.index(obj) | 从列表中找出某个值第一个匹配项的索引位置 | |
| list.insert(index, obj) | 将对象插入列表 | |
| list.pop([index=-1]) | 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 | |
| list.reverse() | 反向列表中元素 | |
| max(list) min(list) | 返回元素最值 | |
| list.count(obj) | 统计某个元素在列表中出现的次数 | |
| list.extend(seq) | 在列表末尾一次性追加另一个序列中的多个值 | |
| list(seq) | 元组转换为列表 | |
| ‘,’.join(list) | list转str | 已逗号分隔每个item |
| str.split(“,”) | str转list | str已逗号分割为item |
list(set(a).intersection(set(b))) | list a和b求交集 | |
list(set(a).union(set(b))) | list a和b求并集 | |
list(set(b).difference(set(a))) | list a和b求差集; b中有而a中没有 | |
| set(aList) | 列表去重 |
4)Tuple(元组)
元组用 () 标识。内部元素用逗号隔开。但是元组不能二次赋值,相当于只读列表。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
tuple = ( 'runoob', 786 , 2.23, 'john', 70.2 )
tinytuple = (123, 'john')
print tuple # 输出完整元组
print tuple[0] # 输出元组的第一个元素
print tuple[1:3] # 输出第二个至第四个(不包含)的元素
print tuple[2:] # 输出从第三个开始至列表末尾的所有元素
print tinytuple * 2 # 输出元组两次
print tuple + tinytuple # 打印组合的元组
i>list( tup ) 元组转列表
#!/usr/bin/python
# -*- coding: UTF-8 -*-
aTuple = (123, 'xyz', 'zara', 'abc');
aList = list(aTuple)
print "列表元素 : ", aList
ii>namedtuple(具名元组,python3)
具名元组即带字段名的元组,实例和普通元组消耗的内存一样多,因为字段名都被存在对应的类里面。
import collections
## typename:元组名称
## field_names: 元组中元素的名称
## rename: 如果元素名称中含有 python 的关键字,则必须设置为 rename=True
collections.namedtuple(typename, field_names, verbose=False, rename=False)
#另一种:User = collections.namedtuple('User', ['name', 'age', 'id'])
User = collections.namedtuple('User', 'name age id')
user = User('tester', '22', '464643123')
#User(name='tester', age='22', id='464643123')
print(user)
# 获取所有字段名
print( user._fields )
# 也可以通过一个list来创建一个User对象,这里注意需要使用"_make"方法
user = User._make(['Runoob', 'male', 12])
# 获取用户的属性
print( user.name )
# 修改对象属性,注意要使用"_replace"方法
user = user._replace(age=22)
# 将User对象转换成字典,注意要使用"_asdict"
print( user._asdict() )
from collections import namedtuple
Field = namedtuple("Field", ["field", "is_preset", "id"])
#数据库访问结果赋值
rows = client.query_all(sql);
fields = [Field (row[0], row[1], row[2]) for row in rows]
5)Dictionary(dict,字典)
- k-v格式:索引key && 值value
k唯一 - 用"{ }"标识
d = {key1 : value1, key2 : value2 }
1>语法
#!/usr/bin/python
# -*- coding: UTF-8 -*-
dict = {}
## 值修改
dict['one'] = "This is one"
dict[2] = "This is two"
## 初始化
tinydict = {'name': 'john','code':6734, 'dept': 'sales'}
## 值访问
print dict['one'] # 输出键为'one' 的值: This is one
print dict[2] # 输出键为 2 的值: This is two
print tinydict # 输出完整的字典
print tinydict.keys() # 输出所有键:['dept', 'code', 'name']
print tinydict.values() # 输出所有值
#遍历方式(3钟):
for key in dict:
print(key+':'+dict[key])
for key in dict.keys():
print(key+':'+dict[key])
for key,value in dict.items():
print(key+':'+value)
## 值删除
tinydict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
del tinydict['Name'] # 删除键是'Name'的条目
tinydict.clear() # 清空字典所有条目
del tinydict # 删除字典
2>字典常用函数及方法:
| 函数 | 说明 | 备注 |
|---|---|---|
| len(dict) | 键的总数 | |
| dict.clear() | 删除字典内所有元素 | |
| dict.get(key, default=None) | 返回指定键的值,如果值不在字典中返回default值 | |
| dict.setdefault(key, default=None) | 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default | |
| dict.has_key(key) | 如果键在字典dict里返回true,否则返回false | |
| dict.keys() | 以列表返回一个字典所有的键 | |
| dict.values() | 以列表返回字典中的所有值 | |
list(dict.values()) | dict转list | |
| pop(key[,default]) | 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。 | |
| dict1.update(dict2) | 2个dict合并 |
6)数据类型转换
| 函数 | 描述 |
|---|---|
| int(x [,base]) | 将x转换为一个整数 |
| long(x [,base] ) | 将x转换为一个长整数 |
| float(x) | 将x转换到一个浮点数 |
| complex(real [,imag]) | 创建一个复数 |
| str(x) | 将对象 x 转换为字符串 |
| repr(x) | 将对象 x 转换为表达式字符串 |
| eval(str) | 用来计算在字符串中的有效Python表达式,并返回一个对象 |
| tuple(s) | 将序列 s 转换为一个元组 |
| list(s) | 将序列 s 转换为一个列表 |
| set(s) | 转换为可变集合 |
| dict(d) | 创建一个字典。d 必须是一个序列 (key,value)元组。 |
| frozenset(s) | 转换为不可变集合 |
| chr(x) | 将一个整数转换为一个字符 |
| unichr(x) | 将一个整数转换为Unicode字符 |
| ord(x) | 将一个字符转换为它的整数值 |
| hex(x) | 将一个整数转换为一个十六进制字符串 |
| oct(x) | 将一个整数转换为一个八进制字符串 |
5,运算符
除了通用的运算符,下面为一些python特有的运算。
| 运算符 | 描述 | 实例 |
|---|---|---|
| ** | 幂 - 返回x的y次幂 | a=10,b=20;a**b 输出结果为10的20次方 |
| // | 取整除 - 返回商的整数部分(向下取整) | 9//2 输出为4;-9//2 输出为-5 |
成员运算符:in(not in)
如果在指定的序列中找到值返回 True,否则返回 False。
a = 10
list = [1, 2, 3, 4, 5 ];
if ( a in list ):
print "1 - 变量 a 在给定的列表中 list 中"
身份运算符:is(is not)
is 是判断两个标识符是不是引用自一个对象。
x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False。
6,结构性语句
1)if-else
#!/usr/bin/python
# -*- coding: UTF-8 -*-
num = 5
if num == 3 and num == 4: # 判断num的值
print 'boss'
elif num == 2 or num == 1:
print 'user'
else:
print 'roadman' # 条件均不成立时输出
2)while-else
count = 0
while (count < 9):
print 'The count is:', count
count = count + 1
count = 0
while count < 5:
print count, " is less than 5"
count = count + 1
else:
print count, " is not less than 5"
3)for-else
else用法和while一致。
for letter in 'Python': # 第一个实例
print '当前字母 :', letter
4)break,continue,pass
pass是空语句,是为了保持程序结构的完整性,一般用于占位。
7,日期和时间
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 引入time模块
import time;
#输出毫秒时间戳
timestamp=long(int(round(time.time() * 1000)))
#格式化时间输出:Thu Apr 7 10:05:21 2016
localtime = time.asctime( time.localtime(time.time()) )
# 格式化成2016-03-20 11:45:39形式
print time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
8,函数
1)函数定义
注意,函数可以传参;但是函数不支持方法重载:函数名一致,参数数量不一致
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 定义函数
def printme( str ):
"打印任何传入的字符串"
print str
return
# 调用函数
printme("我要调用用户自定义函数!")
2)多个返回值
直接返回
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
# 接收:
x, y = move(100, 100, 60, math.pi / 6)
3)random函数
import random
| 说明 | 函数 | 备注 |
|---|---|---|
| 随机生成一个[0,1)之间的浮点数 | random.random() | |
| 产生[a, b]范围内一个随机浮点数 | random.uniform(a, b) | |
| 随机生成[a, b]范围内一个整数 | random.randint(a, b) | |
| 随机生成[a, b]范围内一个整数,step步长可以忽略 | random.randrange(a, b, step) | |
| 从数组中随机选取一个数据 | random.choice(list) | |
| 从数组中随机选取n个数据 | random.sample(list, n) | |
| 打乱一个数组的顺序,返回值为None | random.shuffle(list) |
4)md5
1>不加盐(salt)的md5值
from hashlib import md5
obj = md5()
obj.update("hello python!!!".encode("utf-8"))
bs = obj.hexdigest()
print(bs)
2>加盐(salt)的md5值
from hashlib import md5
salt = "aabbccddeeff"
obj = md5(salt.encode("utf-8")) # 加盐
obj.update("hello python!!!".encode("utf-8"))
bs = obj.hexdigest()
print(bs)
3>扩展sha256的md5值
from hashlib import sha1, sha256
sha = sha256(b'salt')
sha.update(b'hello python!!!')
print(sha.hexdigest())
9,模块(Module)及py相互调用
Module是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
1)使用
support.py 模块:
def print_func( par ):
print "Hello : ", par
return
test.py 文件代码:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 导入模块
import support
# 现在可以调用模块里包含的函数了
support.print_func("Runoob")
或者:
from fib import print_func
print_func("Runoob")
或者:
from modname import *
2)搜索路径
当你导入一个模块,Python 解析器对模块位置的搜索顺序是:
- 当前目录
- 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
- 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/。
模块搜索路径存储在 system 模块的 sys.path 变量中。
在import模块之前可以手动导入模块路径:
import sys
CWD = os.path.dirname(__file__)
sys.path.append(os.path.abspath(os.path.join(CWD, "./common")))
3)在一个py执行另一个py
os.system("python test.py")直接调用cmdresult=os.popen('python test.py')
查询结果:print(result.read())
4)引包路径
import mypackage
print(mypackage.__file__)
5)init.py
import 一个 Package 的时候,它会隐性的去执行 init.py , 而在 init.py 中定义的对象,会被绑定到当前的命名空间里面来。Python3.2 之前,如果当前文件夹是一个模块,必须创建 init.py文件,否则from 文件 import 时会报文件不存在:No module named ruaml。
场景:一般用于做初始化操作,如数据库连接的建立等。
10,异常处理
python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误:
1)异常处理
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
1>try-except-else(捕捉异常)
#!/usr/bin/python
# -*- coding: UTF-8 -*-
try:
fh = open("testfile", "w")
fh.write("这是一个测试文件,用于测试异常!!")
except IOError as e: # 如果不写IOError,表示捕获所有异常
print "Error: 没有找到文件或读取文件失败"
print("没有找到文件或读取文件失败",e)
else:
print "内容写入文件成功"
fh.close()
2>try-finally
无论是否发生异常都将执行最后的代码。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
try:
fh = open("testfile", "w")
fh.write("这是一个测试文件,用于测试异常!!")
finally:
print "Error: 没有找到文件或读取文件失败"
3>with语句
try…finally… 虽然好用,但是代码段有点长。因此python2.5以后引入 with 语句。
with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。
with open('a.txt', 'w') as f:
f.write('Hello!')
4>raise触发异常
raise Exception("元素少于9个噢!")
raise Exception ( "Invalid level!" , level ) # Exception: ('Invalid level!', 0) 运行时错误, def __init__(self, arg):
def functionName( level ):
if level < 1:
raise Exception("Invalid level!", level)
# 触发异常后,后面的代码就不会再执行
5>用户自定义异常
自定义异常类如下:
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
使用:
try:
raise Networkerror("Bad hostname")
except Networkerror,e:
print e.args
2)断言(Assertions)
11,面向对象-类
1)创建类
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Employee:
'所有员工的基类'
empCount = 0
def __init__(self, name, salary): # __init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):# self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。这也是类方法与普通方法的区别。self 代表的是类的实例,代表当前对象的地址,而 self.__class__ 则指向类
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
类的实例化:
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
emp1.displayEmployee() #访问类方法
print "Employee.__doc__:", Employee.__doc__ #类的文档字符串 输出:所有员工的基类
print "Employee.__name__:", Employee.__name__ #类名
print "Employee.__module__:", Employee.__module__ # 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
print "Employee.__bases__:", Employee.__bases__ #类的所有父类构成元素(包含了一个由所有父类组成的元组)
print "Employee.__dict__:", Employee.__dict__ #类的属性(包含一个字典,由类的数据属性组成)
2)对象销毁(垃圾回收)
Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(及未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来, 试图清理所有未引用的循环。
析构函数 del
在对象销毁的时候被调用,当对象不再被使用时运行。
class Point:
def __init__( self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print class_name, "销毁"
3)继承
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Parent: # 定义父类
parentAttr = 100
def __init__(self):
print "调用父类构造函数"
def parentMethod(self):
print '调用父类方法'
def setAttr(self, attr):
Parent.parentAttr = attr
def getAttr(self):
print "父类属性 :", Parent.parentAttr
class Child(Parent): # 定义子类
def __init__(self):
print "调用子类构造方法"
def childMethod(self):
print '调用子类方法'
c = Child() # 实例化子类
c.childMethod() # 调用子类的方法
c.parentMethod() # 调用父类方法
c.setAttr(200) # 再次调用父类的方法 - 设置属性值
c.getAttr() # 再次调用父类的方法 - 获取属性值
- 在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数
- Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
- 同样也支持方法重载,运算符重载
4)类属性与方法
类的私有属性(__private_attrs)
两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的私有方法(__private_method)
两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods
系统方法(foo)
头尾双下划线方法,定义的是特殊方法,一般是系统定义名字 ,类似 init() 之类的。
protected变量(_foo):
以单下划线开头,只能允许本身与子类进行访问,不能用于 from module import *
12,第三方工具连接
1)db连接
- pg连接
import psycopg2
# 获取数据库连接
def get_pg_conn():
conn = psycopg2.connect(dbname=dbname,
user=user,
password=password,
host=host,
port=port)
return conn
# 释放数据库连接
def release_pg_conn(conn):
if (conn is None):
return
try:
conn.close()
except Exception:
logger...
def execute_select_sql(sql):
conn = get_pg_conn()
rows = None
try:
cur = conn.cursor()
cur.execute(sql)
rows = cur.fetchall()
except Exception:
logger...
finally:
release_pg_conn(conn)
return rows
def execute_update_sql(sql):
conn = get_pg_conn()
rows = None
try:
cur = conn.cursor()
cur.execute(sql)
conn.commit()
except Exception:
logger...
finally:
release_pg_conn(conn)
def execute_insert_sql(sql):
conn = get_pg_conn()
cur = conn.cursor()
cur.execute(sql)
rtn = cur.fetchall()
conn.commit()
#关闭连接
cur.close()
conn.close()
return rtn
2)redis连接
1>依赖
pip redis
pip install redis
2>单机连接redis
#!/usr/bin/python
# coding=utf-8
import redis
def test_redis_connect():
# db=0可省略
redis_connect = redis.Redis(host='192.168.xxx.xxx', port=6379, decode_responses=True, password='******', db=0)
if redis_connect is not None:
# 关闭连接
redis_connect.close()
return True
else:
return False
3>连接池连接
import redis
redis_pool = redis.ConnectionPool(
host='192.168.xxx.xxx',
port=16379,
password='******',
db=0,
decode_responses=True)
redis_conn = redis.Redis(connection_pool=redis_pool)
print(redis_conn)
# 关闭连接
redis_pool.disconnect()
4>redis操作
- String操作
set(name, value, ex=None, px=None, nx=False, xx=False)
ex - 过期时间(秒)
px - 过期时间(毫秒)
nx - 如果设置为True,则只有name不存在时,当前set操作才执行
xx - 如果设置为True,则只有name存在时,当前set操作才执行
res = redis_conn.set('kk1', 'vv1', ex=30)
v1 = redis_conn.get('kk1')
print(res)
print(v1)
- List列表
# 表示从左向右操作
redis_conn.lpush("list1", 11, 22, 33)
print(redis_conn.lrange('list1', 0, -1)) # 取出全部。
# 表示从右向左操作
redis_conn.rpush("list2", 11, 22, 33, 44)
print(redis_conn.llen("list2")) # 列表长度。
print(redis_conn.lrange("list2", 0, 3)) # 切片取出值,范围是索引号0-3。
- Hash哈希
redis_conn.hset("hash1", "k1", "v1")
redis_conn.hset("hash1", "k2", "v2")
print(redis_conn.hkeys("hash1")) # 取hash中所有的key
print(redis_conn.hget("hash1", "k5")) # 单个取hash的key对应的值。不存在返回None
print(redis_conn.hmget("hash1", "k1", "k2")) # 多个取hash的key对应的值
- Set集合
redis_conn.sadd("set1", 33, 44, 55, 66) # 往集合中添加元素
print(redis_conn.scard("set1")) # 集合的长度是4
print(redis_conn.smembers("set1")) # 获取集合中所有的成员
- 其他
删除:delete(*names)
检查名字是否存在:exists(name)
设置超时时间:expire(name ,time)
获取类型:type(name)
查看所有元素–迭代器:scan_iter(match=None, count=Non
13,网络通信
1)socket通信
1>服务器端
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:server.py
import socket # 导入 socket 模块
s = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 12345 # 设置端口
s.bind((host, port)) # 绑定端口
s.listen(5) # 等待客户端连接
while True:
c,addr = s.accept() # 建立客户端连接
print '连接地址:', addr
c.send('欢迎访问菜鸟教程!')
c.close() # 关闭连接
2)客户端
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:client.py
import socket # 导入 socket 模块
s = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 12345 # 设置端口号
s.connect((host, port))
print s.recv(1024)
s.close()
2)urllib
urllib的api过于强大,使用的时候需要大量代码;推荐requests。
import urllib
import urllib2
# get请求之urllib、urllib2
def urllib_get():
get_url = 'your url'
params = {"param_one": "XXX",
"param_two": "XXX"
}
params = urllib.urlencode(params)
request = urllib2.Request(url='%s%s%s' % (get_url, '?', params))
result = urllib2.urlopen(request)
return result.read()
# post请求之urllib、urllib2
def urllib_post():
post_url = "your url"
params = {
"param_one": "XXX",
"param_two": "XXX",
}
params_url_encode = urllib.urlencode(params)
request = urllib2.Request(url=post_url, data=params_url_encode)
result = urllib2.urlopen(request)
return result.read()
3)requests
1>依赖安装
requests默认没有安装,安装方法:
windows安装:手动下载解压后在cmd执行安装命令;
shell安装:
- 下载源码
wget https://pypi.python.org/packages/5b/0b/34be574b1ec997247796e5d516f3a6b6509c4e064f2885a96ed885ce7579/requests-2.12.4.tar.gz
- 解压并进入目录,执行脚本
python setup.py install
import requests
# get请求之requests
def requests_get():
get_url = 'your url'
params = {
"param_one": "XXX",
"param_two": "XXX",
}
# verify默认为true,校验SSL证书
request = requests.get(get_url, params=params,verify=False)
return request.content
# post请求之requests
def requests_post():
post_url = 'your url'
params = {
"param_one": "XXX",
"param_two": "XXX",
}
request = requests.post(post_url, json=params)
return request.content
# delete请求
def requests_delete():
delete_url = 'your url'
unique_identifier = 'your Unique identifier' # 删除的唯一标识
result = requests.delete(delete_url + unique_identifier)
return result.content
# put请求
def requests_put():
params = {
"param_one": "XXX",
"param_two": "XXX",
}
put_url = 'your url'
request = requests.put(put_url, json=params)
return request.content
# HTTPBasicAuth
# auth -- (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
from requests.auth import HTTPBasicAuth
response = requests.get('http://localhost:4550',auth=HTTPBasicAuth('username', 'password'))
postman Basic Auth:

14,多线程
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import thread
import time
# 为线程定义一个函数
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print "%s: %s" % ( threadName, time.ctime(time.time()) )
# 创建两个线程
try:
thread.start_new_thread( print_time, ("Thread-1", 2, ) )
thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
print "Error: unable to start thread"
while 1:
pass
15,GUI
16,JSON
import json
数据映射
| python | JSON |
|---|---|
| None | null |
json.dumps
对象编码成 JSON 字符串。
语法:
json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)
参数说明:
- skipkeys=True:在encoding过程中,dict对象的key只可以是string对象,如果是其他类型,那么在编码过程中就会抛出ValueError的异常。skipkeys可以跳过那些非string对象当作key的处理。
- ensure_ascii:输出真正的中文需要指定ensure_ascii=False
- check_circular
- allow_nan
- cls
- indent=2:参数根据数据格式缩进显示,读起来更加清晰;indent的数值,代表缩进的位数。
- separators=(',',':'):去掉,,:后面的空格,美化输出结果。
- encoding
- default
- sort_keys=True:按照字典排序(a到z)输出。
#!/usr/bin/python
import json
data = [ { 'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4, 'e' : 5 } ]
json = json.dumps(data)
print json
向json文件当中写入data数据:
with open("./new.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
python 原始类型向 json 类型的转化对照表:
| Python | JSON |
|---|---|
| dict | object |
| list, tuple | array |
| str, unicode | string |
| int, long, float | number |
| True | true |
| False | false |
| None | null |
json.loads
用于解码 JSON 数据。
#!/usr/bin/python
import json
jsonData = '{"a":1,"b":{"user":[1,2],"type":"image","title":"超人"},"c":3,"d":4,"e":5}';
text = json.loads(jsonData)
print(text["b"]["user"][0]) #输出1
json文件读取:
with open("./new.json", "r", encoding="utf-8") as f:
content = json.load(f)
17,编码规范
代码格式
缩进:4个空格
Python 3中不允许混合使用Tab和空格缩进。
Python 2的包含空格与Tab和空格缩进的应该全部转为空格缩进。
行宽:79字符
续行的首选方法是使用小括号、中括号、大括号、反斜线。比如with语句中:
with open('/path/to/some/file/you/want/to/read') as file_1, \
open('/path/to/some/file/being/written', 'w') as file_2:
file_2.write(file_1.read())
注释
不用行尾注释。
命名规范
规范较多,笔者习惯与java一致,采用驼峰式命名变量及方法。
- 模块名要简短,全部用小写字母,可使用下划线以提高可读性。
- 异常名,类名添加+后缀 “Error”。
- python脚本名称:小写字母+下划线+数字,不要使用“-”

7794

被折叠的 条评论
为什么被折叠?



