一、基础
1.数据类型和变量
#if else语句
name = 'qqqq'
if name=='qqq':
print('true')
print('还是在if里面')
elif:**********
else:
print('false')
#转义字符
print('dfdf\ndsfsd')
#取消转义
print(r'\n\tsdfsfsd')
#多行内容
print('''line1
line2
line3''')
2.list和tuple
#list展示
mylist = ['num1','num2','num3','num4']
length = len(mylist)
#list长度
print(length)
#取值
print(mylist[1])
#取最后一个
print(mylist[-1])#负数代表从后往前第几个数据
#追加数据到list中
mylist.append('num5')
#insert到list中
mylist.insert(1,"num6")
print(mylist)
#删除最后一个
mylist.pop()
#删除指定位置
mylist.pop(1)
###################################
#tuple 类似list,但是建立之后不能修改
mytuple = ('t1','t2','t3')
#定义一个元素的tuple时,在后面加上分号,以免歧义
mytuple1 = (1,)
#tuple是不可变的,但是在里面如果有list,知识说明list的头指针不变,但是里面的内容是可以变的。
3.循环语句
#for 循环
sum=0
mylist = [1,2,3,4,5]
for i in mylist:
sum=sum+i
print(sum)
sum1 = 0
#range(n)是指0到n-1之间的整数
for j in range(101):
sum1+=j
print(sum1)
#while循环
while sum1 > 100:
sum1-=100
4.dict和set
#dict(即key-value对)
d={'num1':1,'num2':2,'num3':3}
print(d['num2'])
#也可以赋值
d['num2']=100
#取数据
#直接取d['num2']
#使用get取
result = d.get('num2',-1)#好处是娶不到可以用默认值,不会报错
#也可以先判断在不在里面
if 'num2' in d:
result = d['num2']
else:
result = -1
#pop删掉
d.pop('num2')
#set
s=set([1,2,3])
s.remove(1)#删掉元素1,而不是第几个元素,因为set内部元素没有次序
#set的交际并集采用&和|
5.函数
常用简单内置函数:
abs
,max
,hex
,int()
转换成int,float()
转换成float
新建myfunction.py文件,
def my_abs(x):
if not isinstance(x, (int, float)):#判断类型,只有整形和浮点型才行
raise TypeError('bad operand type')
if(x>=0):
return x
else:
return -x
内容就是求绝对值,
然后再在调用的py里面,
from myfunction import my_abs
i=my_abs(-5)
print(i)
使用from指明函数来自哪里,使用import知名要导入哪个函数。
返回多个值可以直接逗号分开,其实就是返回的tuple
python会记得默认参数的值,因此默认参数一定要只想不变对象!可以使用None代替
def add_end(L=None):
如果不确定入参数量,可以用list或者tuple传入,但是需要组装一个list,优点麻烦。python有可变入参,在参数名前面加上*号就行了,在里面把这个入参当做list使用。
python支持关键字传参。比如
def person(name, age, **kw): print('name:', name, 'age:', age, 'other:', kw)
这个方法,我可以这样调用
person('Adam', 45, gender='M', job='Engineer')
,得到的结果是:
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
很厉害是不是!特别是在一些上传数据的情况,不一定每一个都上传,只需要把需要的整合一下上传就好。有点类似于builder模式。
6.切片(字符串截取)
mylist = ['num1','num2','num3','num4']
print(mylist[1:3])
使用[:]方式来进行,[1:2:3]每隔3个取一个数
7.列表生成器
[x * x for x in range(1, 11)]
就生成了[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
还能跟上条件语句
[x * x for x in range(1, 11) if x % 2 == 0]
[s.lower() for s in L]
#全部转小写
二.函数式编程
1.高阶函数
函数名可以赋值给某一个变量,如下:
a=abs
print(a(-10))
将abs函数赋值给a,照样能够用a()来代表原来的abs()
高阶函数就是能够将函数作为参数传递,比如下面
def add(x, y, f):
return f(x) + f(y)
2.map/reduce编程
map就是对每一个元素进行操作,比如我想计算list中每一个元素的平方,可以这样写
def f(x):
return x*x
r=map(f,[1,2,3,4,5])
print(list(r))
reduce和map相反,reduce是对整体的list进行操作,比如想对整个list求和:
from functools import reduce
def fn(x,y):
return x+y
i = reduce(fn,[1,2,3,4,5])
print(i)
map树输入整体,一个一个计算,输出一个整体。reduce是输入整体,函数是一个一个计算,最后输出一个数。reduce需要引入functools文件中的reduce库
面向对象的编程
1.定义类,然后都按照类来操作
class Student(object):
def __init__(self,name,score):
self.name = name
self.score = score
def print_score(self):
print('%s:%s' % (self.name,self.score))
bart = Student("bart",100)
lisa = Student('Lisa',60)
bart.print_score()
lisa.print_score()
如上,使用init来进行构造,构造的第一个参数放入self,相当于this,其余的function都需要放入self。但是调用的时候不需要传入self。
访问权限
如果不想变量被外部访问,在前面加上两个_就行,比如上面的就变成:
self.__name = name
self.__score = score
这样就需要先通过类名在访问变量名,即_Student__name这样访问。不建议这么做,因为python可能会把内部的变量名改掉。
通过getset方式进行数据赋值控制。
继承
class Dog(Animal):
其实这就让Dog继承了Animal
python是一种动态语言,当需要一个A类型是,不一定传入A,可以传入一个和A中函数名一样的类。而静态语言(如java)中就不行。
动态语言创建一个类,可以为这个对象添加额外的属性。
对象类型
使用type可以判断属于哪一种类型,
type(123)==int
是True
对于class的继承关系,使用isinstance(),子类的对象属于父类的实例,而父类创建的对象就不属于子类的instanse。
为实例添加属性和方法
from types import MethodType
class Student(object):
pass
#为实例添加属性name
s=Student()
s.name = 'hond'
print(s.name)
#为实例添加方法设置name
def setname(self,name):
self.name = name
Student.setname = setname
s.setname('jack')
print(s.name)
设置属性的时候直接设置就行,设置方法的时候,先定义方法,定义的时候要把对象使用sel传递进去。然后再使用MethodType将方法赋值给对象,之后就能调用了。
使用slots来限制绑定的属性,比如:
class Students(object):
__slots__=('name','age')
就只允许添加name和age的属性。slots属性只对自己有效,对子类是没有效果的
属性的读写
可以使用@property来控制读,使用@属性名.setter来控制属性的写
@property
def birth(self):
return self._birth
@birth.setter
def birth(self, value):
self._birth = value
上面代码中,birth可以直接读取,也可以直接写入
错误处理代码
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally...')
print('END')
三. IO文件操作
读取文件
f = open('/Users/michael/test.txt', 'r')
for line in f.readlines():
print(line.strip()) # 把末尾的'\n'删掉
内存读写
(1)使用StringIO操作string数据,有两种方式
from io import StringIO
f=StringIO()
f.write('dddddddd')
f.getValue()
还有一种
from io import StringIO
f=StringIO('Hello!\nHi!\nGoodbye')
while True:
s = f.readline()
if s=='':
break
print(s)
读写多行的数据
(2)使用BytesIO操作二进制数据
from io import BytesIO
f = BytesIO()
f.write(b'\xe4\xb8')
序列化
(1)固化到文件的序列化
python中的序列化叫pickling
import pickle
#将一个dict写进文件,二进制
f=open('1.txt','wb')
d=dict(name='hond',age=20,score=80)
pickle.dump(d,f)
f.close()
#从文件读取
g=open('1.txt','rb')
d=pickle.load(f)
g.close()
print(d)
(2)json序列化
import json
d=dict(name='hond',age=20,score=88)
print(json.dumps(d))
对于类的json,可以先将类转换成dict,再序列化
四.进程和线程
1.创建简单进程
from multiprocessing import Process
import os
# 子进程要执行的代码
def run_proc(name):
print('Run child process %s (%s)...' % (name, os.getpid()))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start()
p.join()
print('Child process end.')
使用multiprocessing创建Process类,初始化时分配给这个进程任务。然后使用start和join进行控制
2.创建多个子进程
使用Pool进程池
from multiprocessing import Pool
import os, time, random
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Pool(4)
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')
使用Pool分配进程池的个数,然后运行,使用join等待所有子进程结束。
进程间通信时通过pip管道和Queue数据队列进行的。
3.多线程
使用threading.Thread分配新的Thread,并且指定这个Thread干的事情和名字
import time, threading
# 新线程执行的代码:
def loop():
print('thread %s is running...' % threading.current_thread().name)
n = 0
while n < 5:
n = n + 1
print('thread %s >>> %s' % (threading.current_thread().name, n))
time.sleep(1)
print('thread %s ended.' % threading.current_thread().name)
print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print('thread %s ended.' % threading.current_thread().name)
使用threading.Lick()来获取锁,然后再lock.acquire()和lock.release()释放锁
balance = 0
lock = threading.Lock()
def run_thread(n):
for i in range(100000):
# 先要获取锁:
lock.acquire()
try:
# 放心地改吧:
change_it(n)
finally:
# 改完了一定要释放锁:
lock.release()
使用ThreadLocal来管理每一个线程自己的独立数据。
五.常用内建模块
1.datetime
datetime是处理日期和时间的标准库,
基本用法如下:
from datetime import datetime
#获取当前时间
now = datetime.now()
print(now)
#设置指定日期和时间
dt = datetime(2017,3,29,12,20)
print(dt)
#将时间转换成timestamp
ts1 = now.timestamp()
print(ts1)
ts2 = dt.timestamp()
print(ts2)
#从timestamp转换到时间
dt2 = datetime.fromtimestamp(ts2)
print(dt2)
#到utc标准时间
dt3 = datetime.utcfromtimestamp(ts2)
print(dt3)
2.一些集合(collections模块)
deque
双向链表
defaultdict
key不存在是返回‘N/A’
orderedDict
表示key有序的map,相当于linkehashmap。按照插入的key的顺序排列。
3.使用hashlib模块进行摘要运算,比如MD5,sha1等等
4.使用with语句进行资源的调用
这一点和C#很类似,使用with调用资源,在with块结束的时候系统会自动释放这个资源。比如:
with open('/path/to/file', 'r') as f:
f.read()
一般的类也可以采用with,但是毕竟需要释放资源,因此需要写好AOP的两个函数,一个是with开始的wnter函数,表示with开始,一个是exit函数,表示with结束,清理一些资源
既然说到了AOP,其实这一段也可以使用pythod的AOP @contextmanager
来进行,
@contextmanager
def create_query(name):
print('Begin')
q = Query(name)
yield q
print('End')
开始时begin,结束时采用yield进行结束。
如果一个对象没有上下文,可以使用closing
进行资源关闭,一样可以用在with中
5.urllib进行数据获取
下面代码获取一个api的数据
from urllib import request
with request.urlopen('https://api.douban.com/v2/book/2129650') as f:
data = f.read()
print('Status:', f.status, f.reason)
for k, v in f.getheaders():
print('%s: %s' % (k, v))
print('Data:', data.decode('utf-8'))
目前已经出了urllib2,可以代替原先的urllib,使用urllib2.urlopen
和urllib2.Request
进行数据请求
六.IO
1.协程
协程是更加轻量级的线程,但是不需要耗费线程之间的切换代价,因此,使用协程有时候是最好的方案
下面的代码是哟个生产者和消费者模型
def consumer():
r = ''
while True:
n = yield r
if not n:
return
print('[CONSUMER] Consuming %s...' % n)
r = '200 OK'
def produce(c):
c.send(None)
n = 0
while n < 5:
n = n + 1
print('[PRODUCER] Producing %s...' % n)
r = c.send(n)
print('[PRODUCER] Consumer return: %s' % r)
c.close()
c = consumer()
produce(c)
produce使用send提供生产的数据,并且有返回值,consumer接收到数据后,使用yield接收到r这个返回参数,并且将这个返回参数填上返回数据,producer之后就能够接收到consumer返回的数据了。
2.asyncio
这个库在python3.4才引入进来
原理就是直接使用asyncio获取一个EventLoop的引用,将需要执行的协程直接扔到这个EventLoop中去就行。
如下
import asyncio
@asyncio.coroutine
def hello():
print("Hello world!")
# 异步调用asyncio.sleep(1):
r = yield from asyncio.sleep(1)
print("Hello again!")
# 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()
上面代码中,使用@asyncio.coroutine
这个注解告诉编译器,这个里面有异步io,使用yield开始进行协程运算。
3.async/await
python3.5中引入
async def hello():
print("Hello world!")
r = await asyncio.sleep(1)
print("Hello again!")
使用上和其他语言的async/await没什么区别