python学习
在项目的过程中需要使用svn hooks来做一些权限控制的操作,一开始使用shell来实现,在实现完成之后某些模块返回的json格式有所变化,需要修改shell的实现,shell对于json的解析很麻烦,线上的机器又不能引入别的库,于是考虑使用python来做这项工作,下面列出使用过的python语言点,纯记录作用,没有技术含量。。
python语言本身跟Java的区别:
- python用缩进来替代{/},所以在vim中开发python的时候需要配置下。
- python里不包括自增/自减运算符。但是有相应的+=、-=、*=运算符。
- python里的布尔运算符有and和or,Python还支持取反的布尔运算符not。
- python中字符串跟list,map直接拼接是会报错的(str+list会报错)
python语言特性相关:
python特点:缩进、字节码、动态语义。
python要学会用三内置剑客:type,help,dir.
基本语法:
一切数据都是对象,一切变量都是对数据对象的引用。
python内部的引用计数。(sys.getrefcount(a))
python可以多重赋值。(a,b,c = 4,5,"abc")
python删除。(del a)
python对象具有三个特性:身份(id方法用于查看唯一的标识符)、类型(type方法用于查看类型)、值。
三特性在对象创建时被赋值。只有值可以改变,其他只读。
Null与None是Python的特殊类型,Null对象或者是None Type,它只有一个值None.
它不支持任何运算也没有任何内建方法.
None和任何其他的数据类型比较永远返回False。None有自己的数据类型NoneType。你可以将None复制给任何变量,但是你不能创建其他NoneType对象。
python常用数据类型:
- int 整型
- boolean 布尔
- string 字符串
- tuple 元祖
- list 列表
- dict 字典
前四种为不可变类型,后两种为可变类型。
字符串认知与应用
1.字符串概念(字节串)
2.ascii unicode utf8到底是啥
3.python默认的编码是ascii.
4.len之需注意
a="哈" len(a) a=u"哈" len(a) a="哈".decode('utf-8')
5.字符串前面跟着的小尾巴到底是什么东西
a=u"哈哈"
a=r"\n"(不要转义)
6.字符串拼接
超级丑陋之千万别用。(a+b) 浪费性能,不推荐使用
可选方案之字符串模板 %s %d 占位符
优秀的拼接方案
"".join([a,b,c])
","join([a,b,c])
7.格式化研究
% 格式化方式
format格式化方式
"this is {} {} ".format("my", "apple")
"this is {1} {0} ".format("my", "apple")
"this is {whose} {first} ".format(whose = "my", first = "apple")
还有一个方法,字典来了。
python包含6种内建的序列:列表、元组、字符串、Unicode字符串、buffer对象和xrange对象。 列表和元组的区别在于:列表可以修改,元组则不能。
通用序列操作:
- 索引(使用负数时候,会从右边开始数,最右的索引编号为-1)
- 分片(访问一定范围内的元素,前取后不取)
- 相加
- 乘法
- 成员资格(in操作符)
- 长度,最大值,最小值(len max min 三个函数)
#索引 >>>greeting='hello' >>>greeting[0] 'h' #分片 >>>greeting='hello' >>>greeting[1:3] >'el' #相加 >>>[1,2,3] + [4,5,6] [1,2,3,4,5,6] >>>'hello,' + 'world' 'hello,world' #乘法 >>>'yhw' * 5 'yhwyhwyhwyhwyhw' #成员资格 >>>permission = 'rw' >>>'w' in permission True
列表:
添加操作:
+ 生成一个新的列表
extend:接受参数并将该参数的每个元素都添加到原有的列表中,原地修改列表而不是新建列表
append :添加任意对象到列表的末端
insert: 插入任意对象到列表中,可以控制插入位置。
修改列表:
修改列表本身只需要直接赋值操作就行。
A = [1,2,3]
A[0]=’haha’
删除操作:
Del :我们通过索引删除指定位置的元素。
del a[1]
del a[:] 删除元素
Remove:移除列表中指定值的第一个匹配值。如果没找到的话,会抛异常。
a.remove(4)
Pop:返回索引下标的元素,并从list删除它。
a.pop(0):返回第一个元素,并从list中删除它。
列表推导式:
[expr for iter_var in iterable]
首先迭代iterable里所有内容,每一次迭代,都把iterable里相应内容放到iter_var中,再在表达式中应用该iter_var的内容,最后用表达式的计算值生成一个列表。
比如我们要生成一个包含1到10的列表
[x for x in range(1,11)]
[expr for iter_var in iterable if cond_expr]
加入了判断语句,只有满足条件的内容才把iterable里相应内容放到iter_var中,再在表达式中应用该iter_var的内容,最后用表达式的计算值生成一个列表。
要生成包含1到10的所有奇数列表。
range(1,11,2)
[x for x in range(1,11) if x % 2 == 1]
排序翻转:sort,reverse
a = [33,11,22,44]
这个方式直接修改原列表。他的返回值为none,所以
b = a.sort()
print b 输出的内容是None
我们直接输出a列表变量
list的reverse函数:反转一个list, 他的返回值为none
比如上面的列表a
b = a. reverse()
print b 输出的内容是None
直接看a列表变量能看到翻转的效果。
内置list方法。
返回一个列表,参数是可迭代对象
xrange和range的区别
xrange生成一个xrange对象,range生成一个列表对象。
列表推导式再应用
[x*x for x in range(100)]
['the %s' % d for d in xrange(10)]
[(x,y) for x in range(2) for y in range(2)]
dict([(x,y) for x in range(2) for y in range(2)])
元组:
属于不可变的对象,不能在原地修改内容,没有排序,修改等操作。
tuple类型转换
那为什么有列表还要有元组呢?
元组不可变的好处。保证数据的安全,比如我们传给一个不熟悉的方法或者数据接口,
确保方法或者接口不会改变我们的数据从而导致程序问题。
集合:
集合是没有顺序的概念。所以不能用切片和索引操作。创建集合。set():可变的 不可变的frozenset():
添加操作: add,update
删除 remove
成员关系 in,not in
交集,并集,差集 & | -
set去重 列表内容元素重复
#encoding=utf-8 ##可变集合 info = set('abc') info.add('python')##添加单个对象到集合里 print info info.update('python')##把对象里的每个元素添加到集合里 print info info.remove('python') print info ##不可变集合 t = frozenset('haha')##不能进行添加,修改和删除的操作。 ##成员操作 in,not in print 'a' in info print 'h' in t print 'jay' not in info ##判断2个集合是否相等,之和元素本身有关,和顺序无关。 print set('abc') == set('cba') ##并集,交集,差集 print set('abc') | set('cbdef')##并集 print set('abc') & set('cbdef')##交集 print set('abc') - set('cbdef')##差集 liststr = ['haha','gag','hehe','haha'] #for循环 m = [] for i in liststr: if i not in m: m.append(i) print m m = set(liststr) print list(m)
字典:
字典是无序的,它不能通过偏移来存取,只能通过键来存取。
字典 = {'key':value} key:类似我们现实的钥匙,而value则是锁。一个钥匙开一个锁
特点:
内部没有顺序,通过键来读取内容,可嵌套,方便我们组织多种数据结构,并且可以原地修改里面的内容,属于可变类型。
组成字典的键必须是不可变的数据类型,比如,数字,字符串,元组等,列表等可变对象不能作为键。
1 创建字典。
info = {'name':'lilei', 'age': 20}
info = dict(name='lilei',age=20)
2 添加内容 a['xx'] = 'xx'
比如 info['phone'] = 'iphone5'
3 修改内容 a['xx'] = 'xx' ,
info['phone'] = 'htc'
update 参数是一个字典的类型,他会覆盖相同键的值
info.update({'city':'beijing','phone':'nokia'})
htc 变成了nokia了
4 删除 del,clear,pop
del info['phone'] 删除某个元素
info.clear()删除字典的全部元素
info.pop('name')
5 in 和 has_key() 成员关系操作
比如:
1 phone in info
2 info.has_key('phone')
6 keys(): 返回的是列表,里面包含了字典的所有键
values():返回的是列表,里面包含了字典的所有值
items:生成一个字典的容器:[()]
7 get:从字典中获得一个值
info.get('name')
info.get('age2','22')
python语句讲解
1.print语句
1.1 基本输出
1.2 print的逗号(不分行)
1.2 输出到文件 >>为重定向
print >> f, "hahahaha"
print >> f, "xixixixixi"
2.控制流语句(control flow)
2.1 由条件和执行代码块组成。(python中没有switch)
2.2 格式(冒号与4个空格永不忘)
3.布尔值
3.1 控制流与真假值息息相关
3.1.1 不要误解了真假与布尔值
3.2 布尔值的几个最基本运算符
3.2.1 and
3.2.2 or
3.2.3 is 检查共享
3.2.4 == 检查值
3.2.5 not
3.2.6 其他若干比较符号
4. if语句 (控制流语句)
4.1 if的组成 if else elif pass
4.1.1 if与elif替代了switch
4.1.2 pass
4.2 奇技淫巧 三元表达式
4.2.1 x if else(4 if True else 3)
4.2.2 活用list([4,3][True])
4.2.3 三元表达式玩玩就好
5. while语句
5.1 while的基本组成部分
break 结束while
continue 跳出当前这次循环,但不结束while
6.for语句
6.1 for的基本格式
for item in iterable:
statement(s)
6.2 for的基本组成部分
3.2.1 break
3.2.2 continue
3.2.3 else
6.3 注意:for的最后一个迭代值将保留
7.好玩的translate与maketrans
import string
g = string.maketrans('i', 'I')
print a.translate(g)
print a.translate(g,'123') 逐字删除
8.一个新的语句,with(会自动关闭)
with open('a.txt','a') as g:
g.write("xixixixi")
函数:
1.如何定义函数
def是关键词,括号冒号永不忘
没有return的函数,不是真函数
不写doc的函数,就像没有性别的人类。
print a.__doc___
2.函数的参数魔法和陷阱
如何定义参数(位置参数、可选参数 a = 4)
参数的值是局部变量
global b(不是好习惯)
参数默认值
如何修改参数
不建议直接修改参数,没有返回值。建议用返回值的方式
魔法参数
** 字典
* 元组
3.参数分为可选参数必须的参数
var1 = None
可选参数 是有默认值的、必须参数 是没有默认值的
4.怎么去学习使用函数
别管那么多复杂的,先直接把功能实现了。抽象成函数:命名规范,伪代码,参数默认值。
自省与函数
func.__code__
dir(func.__code__)
5.函数参数总结
1.位置匹配 func(name)
2.关键字匹配 func(key=value)
3.收集匹配
1.元组收集 func(name,arg1,arg2)
2.字典收集 func(name,key1=value1,key1=value2)
4.参数顺序
参数位置:
1.先是位置匹配的参数
2.再是关键字匹配的参数
3.收集匹配的元组参数
4.收集匹配的关键字参数
初识class
1.如何去定义一个最基本的class
2.class最基本的子元素
3.class传参
4.__init__方法
5.class和函数的区别(python的逻辑是越简单越好,能用函数简单解决的就不用class)
class test(object): """ class的内置方法 """ def __init__(self,var1): self.var1 = var1 """ get被称之为test对象的方法 """ def get(self,a=None): return self.var1 pass """ t是类test的一个实例 """ t = test('test str heiheihei') print t.get() """ 如何去使用对象内置的方法 1.实例化这个class (test) t = test() 2.使用 class.method()的方式去调用 class 的内置方法 注意: 1.当定义一个class的内置方法method时,method的参数的第一个永远是self。 """ class test(object): a = 1 def func_1(self): return self.arg1,self.arg2 def __init__(self,arg1,arg2):##构造函数 self.arg1 = arg1 self.arg2 = arg2 def __del__(self):##析构函数 del self.arg1 del self.arg2 # a 被称为 test的 属性 # func_1 被称为 test的 方法 # 我们所有的class都是object的派生类 t = test(1,4) print t.a print t.func_1()
模块
import
from module import sth
from module import all
import linecachs
from linecachs import getlines
from linecachs import *
常用模块
1.我们去哪里找模块
pypi.python.org python的模块库
2.我们应该首先选择哪些的模块
首先考虑的是,内置模块
文档:http://docs.python.org/2.7/
3.常用模块
3.1 urllib urllib2 网络
3.2 datetime time 时间
3.3 os 系统
3.4 pickle 对象序列化
常用数据交换格式 json xml
3.5 bsddb key=>value
3.6 logging 日志
python字符串拆成多行:
- 使用续行符
- 在()表达式中写
#style1,在python3.x里不支持 a=”aaaaaaaaa” \ “bbbbbbbb” #style2 因为括号中的内容可以写成多行,因此等于先执行一个运算。推荐。 a=(“aaaaaaaaa” “bbbbbbbbb”)
在Python中,任何类型的对象都可以做真值测试,并且保证返回True或者False
以下几种值(不论类型)在真值测试中返回False:
- None
- False
- 任何类型的数字0,包括0,0.0,0L,0j
- 空的序列(sequence)或者映射(mapping)类型对象
- 对于用户自定义类型的对象,如果其类定义了__nonzero__() 或者 __len__()特殊方法并且返回False或者0
判断一个str是为''字符串的方法有如下:
s=' ' if s.strip()=='': print 's is null' #或者 if not s.strip(): print 's is null' 判断一个 list 是否为空 传统的方式: if len(mylist): # Do something with my list else: # The list is empty 由于一个空 list 本身等同于 False,所以可以直接: if mylist: # Do something with my list else: # The list is empty
Python队列:
创建一个“队列”对象 import Queue q = Queue.Queue(maxsize = 10) Queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。 此包中的常用方法(q = Queue.Queue()): q.qsize() 返回队列的大小 q.empty() 如果队列为空,返回True,反之False q.full() 如果队列满了,返回True,反之False q.full 与 maxsize 大小对应 q.get([block[, timeout]]) 获取队列,timeout等待时间 q.get_nowait() 相当q.get(False) 非阻塞 q.put(item) 写入队列,timeout等待时间 q.put_nowait(item) 相当q.put(item, False) q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号 q.join() 实际上意味着等到队列为空,再执行别的操作
python与shell的交互:
shell获取python的返回值:
在调用python的时候不加&:在python中使用sys模块(sys.exit(0)、sys.exit(1)),随后在shell中通过$?或者返回码。
在调用python的时候加&:就不能通过$?捕获退出码,这样的话就麻烦点。一个方案就是:shell 用True循环 ,用ps aux看python是否存在,如果不存在了,代表python运行结束了,或者让python程序结束前产生一个文件,在shell里判断产生的文件在不在,在的话就是正确输出了,不在的话代表python失败了。
python调用shell:
import os
1.os的system方法会创建子进程运行外部程序,方法只返回运行程序完毕后的退出状态。该方法比较适合于外部程序没有输出结果的情况。
2.os的popen方法在需要得到外部程序的输出结果时,很有用。该方法返回一个类文件对象,调用该对象的read()或readlines()方法可以读取输出内容。 打开一个与command进程之间的管道。这个函数的返回值是一个文件对象,可以读或者写(由mode决定,mode默认是’r')。如果mode为’r',可以使用此函数的返回值调用read()来获取command命令的执行结果。
3.commands模块的getoutput方法,这种方法同popen的区别在于popen返回的是一个类文件对象,而本方法将外部程序的输出结果当作字符串返回,很多情况下用起来要更方便些。
4.subprocess模块,python新引入的模块,将要取代上面这些模块。
tips:
python调用shell的时候遇到了一个奇葩的问题:
os.popen("ls -l ruby") #可以调用,显示ruby文件夹下的文件
但是
a = ruby
os.popen("ls -l $a") #就显示的是根目录下的文件
cmd = "ls -l " + a
os.popen(cmd) #这样也不行。
os.popen('ls -l ' + "$a") #这样还是显示的根目录下的文件
但是
os.popen('ls -l ' + 'ruby') #这样就行
必须这样
os.popen('ls -l' + a)
使用python发送http请求:
get请求:
import urllib2 url = '' req=urllib2.Request(url) res_data=urllib2.urlopen(req) res = res_data.read() #以上这种代码在网络环境不好的情况下,常出现read()方法没有任何反应的问题,程序卡死在read()方法里,其实给urlopen方法加上超时即可 res_data=urllib2.urlopen(req,tineout=5)#这里timeout的单位是s,只在python2.6以上版本里有timeout参数 #设置了timeout之后超时之后read超时的时候会抛出socket.timeout异常,想要程序稳定,还需要给urlopen加上异常处理,再加上出现异常重试 try: req = urllib2.Request(url) res_data = urllib2.urlopen(req, timeout = 5) jsonStr = res_data.read() except urllib2.URLError as e: print "Bad URL or timeout" sys.exit(0) except socket.timeout as e: print "socket timeout" sys.exit(0)
urllib vs urllib2:http://www.cnblogs.com/wly923/archive/2013/05/07/3057122.html
给python传参:
import sys
sys.argv[0] sys.argv[1]的这种方式来获取传给python的参数。
但是需要注意的是(ruby参数从0开始,python从1开始):
- sys.argv[1] 第一个参数
- sys.argv[2] 第二个参数
- sys.argv[0] ???这个表是啥
使用python解析json:
python自带的json模块支持对json直接的解析(python 2.7 自带json库,而2.3.x没有自带json库):
import json
s = json.loads(jsonStr)
s.["name"]
s.["type"]["name"]
python读写文件:
python不需要引入任何类库就可以对文件进行读写
#写文件: f = file('/root/test.py','w+') #w复写;a追加写 f.write("print 'hello,world'") f.close()
标准库的linecache:该模块允许从任何文件里得到任何的行,并且使用缓存进行优化,常见的情况是从单个文件读取多行。
linecache.getline('', 1
日常编程中如果涉及读取大文件,一定要使用首选linecache模块,相比open()那种方法要快N倍,它是你读取文件的效率之源。
python正则的使用:
import re
python异常相关:
1.异常的几点注意
1.1 不要没事就乱用异常
慎用异常:
1.找到python的内置异常
2.理解python的内置异常分别对应什么情况
3.阅读你的代码,找到你的代码里可能会抛出内置异常的地方
4.仅对这几行代码做异常处理
假设你无法知道你的代码会抛出什么异常,那么,你的异常处理便是无效的。
1.2 不要一个代码块,大try完事。
1.3 好吧,想try all exception?
sys.exc_info()
1.4 logging如何使用呢
python异常语句简单架构:
try: try_suite except: exception block #上面except子句不跟任何异常和异常参数,所以无论try捕获了任何异常,都将交给except子句的exception block来处理。 try: try_suite except ValueError as e: print "...." #处理特定的异常 try: try_suite except ZeroDivisionError: print "...." except ValueError: print "...." #处理多个异常方式1 try: try_suite except (IOError,TypeError NameError ) as e: print "..." #处理多个异常方式2 try: try_suite except IOError as e: print "..." else: print "..." #try...except...else语句:当没有检测到异常时,执行else语句。 # finally子句是无论是否检测到异常,都会执行的一段代码。我们可以丢掉except子句和else子句,单独使用try...finally,也可以配合except等使用。
python字典对象的Key error检查用if就足够了,比try/except开销低,示例如下:
try: islimited = strInJsonFormat['data']['islimited'] except KeyError as e: print "value Error: the key error" sys.exit(0) #keyerror用if判断足够,比try/except低,建议改成如下: if "data" not in strInJsonFormat: sys.exit(0) if "islimited" not in strInJsonFormat["data"]: sys.exit(0)
断言,一种开发期时检定代码的方式
只断言绝对不能出现的错误 twisted
先断言绝对不能发生的错误,然后,再去处理错误 (异常)
assert 表达式 , "出错以后抛出的message"
多线程:
python里的多线程,不是真正意义上的多线程。因为python具有全局锁,在任意的指定时间里,有且只有一个线程在运行。
import threading import time def test(p): time.sleep(0.001) print p ts = [] for i in xrange(0,15): th = threading.Thread(target=test,args=[i]) th.start() ts.append(th) #for i in ts: # i.join() print "hoho,end!!!!!"
正则表达式:
正则表达式,是字符串检索引擎,最早起源于unix。
1.unix下的正则 awk grep egrep
2.正则的几个基本概念
[0-9] \d 全部数字
\w 单词类字符 a-z A-Z 0-9 _
\W 非单词类字符
{2} {n} 前面的表达式匹配n次
{0,2} {m,n} 前面的表达式匹配m到n次
+ 前面的表达式,出现1到无限次 最少,出现1次
? 前面的表达式,出现0到1次 最多,出现1次
* 前面的表达式,出现0到无限次 出现不出现,都没关系
3.python里的正则模块 re
4.一些基本操作
4.1 一次取配 match:"hello lilei" r'(\w+) (\w+)'
4.2 切割 split
4.3 查找全部 findall
4.4 finditer 迭代器什么的最有爱了
爬虫:
爬取网站的核心:
顺藤摸瓜
1. 爬的是什么域名下的内容
2. 去重。
3. 递归。