python学习

在项目的过程中需要使用svn hooks来做一些权限控制的操作,一开始使用shell来实现,在实现完成之后某些模块返回的json格式有所变化,需要修改shell的实现,shell对于json的解析很麻烦,线上的机器又不能引入别的库,于是考虑使用python来做这项工作,下面列出使用过的python语言点,纯记录作用,没有技术含量。。

python语言本身跟Java的区别:

  1. python用缩进来替代{/},所以在vim中开发python的时候需要配置下。
  2. python里不包括自增/自减运算符。但是有相应的+=、-=、*=运算符。
  3. python里的布尔运算符有and和or,Python还支持取反的布尔运算符not。
  4. 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. 索引(使用负数时候,会从右边开始数,最右的索引编号为-1)
  2. 分片(访问一定范围内的元素,前取后不取)
  3. 相加
  4. 乘法
  5. 成员资格(in操作符)
  6. 长度,最大值,最小值(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字符串拆成多行:

  1. 使用续行符
  2. 在()表达式中写
#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. 递归。

 

posted on 2014-09-01 10:37  神神小堂  阅读(339)  评论(0编辑  收藏  举报

导航