- python运行原理
使用cpython解释器创建栈帧(堆),建立上下文,字节码对象
由于栈帧分配在内存中,所以栈帧可以独立于调用者存在,即使调用完毕依然可以访问
import dis
dis.dis(object) #查看栈帧
------------
def foo(): bar()
def bar():
global frame
frame = inspect.currentframe()
frame.f_back #调用函数 foo()
frame.f_code.co_name # 内部执行函数 bar()
- 迭代器对象,可迭代对象
迭代器 iter, next
可迭代对象 iter, getitem
l = [1,2,3]
for i in l: print i
s = '2323'
for x in s: print x
可迭代对象得到迭代器对象
iter(l)
<listiterator at 0x...>
iter(l) 调用了 l.__iter__()
---------
s.__getitem__() #获取序列
----------
# 得到一个迭代器
t = iter(l)
t.next()
-----------
#实现一个迭代器对象next
#实现一个可迭代对象__iter__方法返回一个迭代器对象
from collections import Iterable, Iterator
# 抽象接口
Iterator.__abstractmethods__ #next
Iterable.__abstractmethods__ #__iter__
#迭代器
class MyIterator(Iterator):
def __init__(self, cities):
self.cities = cities
self.index = 0
def getcity(self, city):
# 处理
return city
def next(self):
if self.index == len(self.cities):
raise StopIteration
city = self.cities[self.index]
"""
try:
city = self.cities[self.index]
except IndexError:
raise StopIteration
"""
self.index += 1
return self.getcity(city)
#可迭代对象
class MyIterable(Iterable):
def __init__(self, cities):
self.cities = cities
def __iter__(self):
return MyIterator(self.cities)
#def __getitem__(self, item):
# return self.cities[item]
#实例化
for i in MyIterable(['beijing','xian']):
print i
# for 实现
myIter = iter(MyIterable(['beijing','xian']))
while True:
try:
print next(myiter)
except Stoplteration:
pass
- 生成器(协程) yield 既有可迭代对象,又有迭代器的特性
使用生成器函数实现可迭代对象
def f():
print 'in f()', 1
yield 1
print 'in f()', 2
yield 2
g = f() #生成器对象,在编译字节码的使用处理
g.next() #1
g.next() #2
#Stopltreation
------------
for x in g:
print x
------------
g.__iter__() is g # True
__iter__() 还是生成器类型,使用yield进行迭代器next
------------
def fib(index):
if index <= 2:
return 1
else:
return fib(index-1) + fib(index-2) #只有最后结果
def fib(index):
ans = []
n, a, b = 0,0,1
while n < index:
ans.append(b)
a, b = b, a+b
n += 1
return ans
def fib2(index):
n, a, b = 0,0,1
while n < index:
yield b #得到每步的值
a, b = b, a+b
n += 1
for i in fib2(10):
print i
--------------
def gen_func():
yield 1
print "hello"
gen = gen_func()
print gen.gi_frame.f_lasti #记录执行最后位置,函数运行控制
print gen.gi_frame.f_locals #维护着当前生成器中的属性字段
生成器案例:看源码 from collections import UserList
大文件读取写入数据库, 100g,只有一行,特殊分隔符;
def myreadline(f, newline):
buf = ""
while True:
while newline in buf:
pos = buf.index(newline)
yield = buf[:pos]
#解析读取文件过长
buf = buf[pos+len(newline):]
chunk = f.read(4096)
# 文件结尾
if not chunk:
yield buf
break
# 读取短
buf += chunk
with open('a') as f:
for line in myreadline(f, '{|}'):
print line
- 线程(io密集),进程(cpu密集),gil(global interpreter lock 全局解释锁),协程
GIL: 一个线程对应c语言一个线程 cpython
同一时刻只有一个线程在一个cpu上执行字节码,无法多个线程映射多个cpu,为了保障线程安全,但不是绝对,因为gil对于cpu的占用会有释放(根据字节码行数|时间片),io操作会释放
https://zhuanlan.zhihu.com/p/110406882
http://www.dabeaz.com/python/UnderstandingGIL.pdf
死锁:1. 不释放 2. 资源竞争
demo:
#加锁 from threading import Lock,RLock
#可重入的锁,同一个线程里可以,可以多次调用acquire,配合使用release
#lock = Lock()
total = 0
def add():
global total
# global lock
for i in range(1000000):
#lock.acquire()
total += 1
#lock.release() #不释放死锁
def desc():
global total
#加锁
for i in range(1000000):
total -= 1
import threading
t1 =threading.Thread(target=add)
t2 =threading.Thread(target=desc)
t1.start()
t2.start()
t1.join()
t2.join()
#total 随机
还有线程同步,线程池,进程通信,进程池
线程:threading
thread = threading.Thread(target=test)
thread.start()
thread.join()
进程:mutilprocess
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
jobs.append(p)
p.start()
协程:
阻塞(函数调用,函数被当前线程挂起),非阻塞(立即返回),并发, 并行,同步(发送消息,等待IO),异步
IO多路复用 socket,select,epoll,poll
io模型:阻塞io,非阻塞io, io多路复用,信号驱动io,异步io匿名函数lambda
列表表达式
装饰器 *args *kargs
为多个函数添加同一个功能
def fib(n):
if n <=1:
return 1
return fib(n-1) + fib(n-2)
----------
def fib(n):
if cache is None:
cache = {}
if n in cache:
return cache[n]
if n <= 1:
return 1:
cache[n] = fib(n-1, cache) + fib(n-2, cahce)
return cache[n]
------
def memo(func):
cache = {}
def warp(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return warp
#fib = memo(fib)
@memo
def fib(n):
...
- 单例模式
class single(object):
_instances = None
def __new__(cls, *args, **kargs):
if cls._instances is None:
cls._instances = object.__new__(cls, *args, **kargs)
return cls._instances
def __init__(self):
pass
- 类的加载
- 常用库 requests, collections, re, MySQLdb,
https://docs.python.org/zh-cn/3.7/library/index.html - 常用框架 celery , django