python高级编程技巧
http://blog.sina.com.cn/s/blog_a89e19440101fb28.html
Python列表解析语法[]和生成 器()语法类似
[expr for iter_var in iterable] 或 [expr for iter_var in iterable if cond_expr]
例子:[i for i in range(10)if i %2==0]
Enumerate
>>> i=0
>>> s=[‘a‘,‘b‘,‘c‘]
>>> s
[‘a‘, ‘b‘, ‘c‘]
>>> for t in s:
... s[i]=‘%d:%s‘%(i,s[i])
... i+=1
...
>>> s
[‘0:a‘, ‘1:b‘, ‘2:c‘]
for i,s1 in enumerate(s):
s[i]=‘%d:%s‘%(i,s[i])
enumerate(iterable[, start]) -> iterator for index, value of iterable
>>> def _s(a,b):
... return ‘%d:%s‘%(a,b)
>>> s=[‘a‘,‘b‘,‘c‘]
>>> s
[‘a‘, ‘b‘, ‘c‘]
>>> [_s(i,t)for i ,t in enumerate(s)]
[‘0:a‘, ‘1:b‘, ‘2:c‘]
>>>
如果要对序列进行循环的时候,尝试使用列表解析来解决问题
迭代器
Next下一个项
__iter__迭代器本身
>>> i=iter(‘abc‘)
>>> dir(i)
[‘__class__‘, ‘__delattr__‘, ‘__doc__‘, ‘__format__‘, ‘__getattribute__‘, ‘__has
h__‘, ‘__init__‘, ‘__iter__‘, ‘__length_hint__‘, ‘__new__‘, ‘__reduce__‘, ‘__red
uce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__
‘, ‘next‘]
>>> i.__iter__
<method-wrapper ‘__iter__‘ of iterator object at 0x000000000271F8D0>
>>> i.next()
‘a‘
>>> i.next()
‘b‘
>>> i.next()
‘c‘
>>> i.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
例子:>>> class M(object):
... def __init__(self,s):
... self.s=s
... def next(self):
... if self.s<=0:
... raise Exception
... self.s-=1
... return self.s
... def __iter__(self):return self
...
>>> for s1 in M(10):
... print ‘self.s是:%s‘%(s1)
生成器
Next进行生成 的
send是除next外另一个恢复生成器的方法
例子:
>>> def f():
... a,b=0,1
... while 1:
... yield b
... a,b=b,b+a
...
>>> x=f()
>>> dir(x)
[‘__class__‘, ‘__delattr__‘, ‘__doc__‘, ‘__format__‘, ‘__getattribute__‘, ‘__has
h__‘, ‘__init__‘, ‘__iter__‘, ‘__name__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex_
_‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘, ‘clo
se‘, ‘gi_code‘, ‘gi_frame‘, ‘gi_running‘, ‘next‘, ‘send‘, ‘throw‘]
>>> x.next()
1
>>> x.next()
1
>>> x.next()
2
>>> x.next()
3
>>> x.next()
5
>>> x.next()
8
>>> x.next()
13
>>> x.next()
21
>>> x.next()
34
>>>
当要返回一个序列或者循环中执行的函数就要考虑生成器.
s=open(r‘C:\Users\Administrator\Desktop\l1.py‘).next()
s1=tokenize.generate_tokens(s)
s1.next()
例子:
>>> def p(s):
... for v in s:
... print ‘%s‘%v
... yield v
...
>>> def adds(v):
... for s in v:
... print s
... if s%2==0:
... yield s+3
... else:
... yield s+2.7-0.7
...
>>> sq=[1,4,7,9,12,19,0]
>>> r=adds(p(sq))
>>> r.next()
1
1
3.0
>>>
S.endswith(suffix[, start[, end]]) -> bool
Str.endswith(‘!s’)
Yield可以变成表达式
比如
S=(yiled)
send(...)
send(arg) -> send ‘arg‘ into generator,
return next yielded value or raise StopIteration.
Send(object)
Throw允许客户端代码传入要抛出的任何类型异常
Close工作方式相同,它抛出的异常是:GeneratorExit
如果是close的异常,生成器函数必须再次抛出GeneratorExit
或者StopIteration异常
Multitask协同程序,可以用于挂起,恢复,有多个进入点函数
在python里面协同程序就是用来代替线程
import contextlib
import greenlet(需要安装)下载地址:https://pypi.python.org/pypi/greenlet#downloads
Multitask下载地址:http://code.google.com/p/python-multitask/
直接把Multitask复制到python安装即可,然后可以使用
例子:
在协同程序之间的协作,经典是例子是接受多个客户查询,并将每个查询委托给对此做出响应新纯种服务器应用程序。
from __future__ import with_statement
from contextlib import closing
import multitask,socket
def clicket(sock):
with closing(sock):
while 1:
data=(yield multitask.recv(sock,1024))
if not data:
break
yield multitask.send(sock,data)
def echo_(host,poc):
addri=socket.getaddrinfo(host,poc,socket.AF_UNSPEC,socket.SOCK_STREAM)
(fa,so,pr,ca,so1)=addri[0]
with close(socket.socket(fa,so,pr))as s1:
s1.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s1.bind(so1)
s1.listen(5)
while 1:
multitask.add(clicket((yield multitask.accept(s1))[0]))
import sys
if __name__==‘__main__‘:
host=None
pors=1111
if len(sys.argv)>1:
host=sys.argv[1]
if len(sys.argv)>2:
pors=sys.argv[2]
multitask.add(echo_(host,pors))
try:
multitask.run()
except Exception:
Pass
#注:yield必须使用在函数内
但可以使用生成器()来代替yield语句
例如:
A=[b for b in range(b)if b%2==0]
For s in A:print s
迭代器模块(高级:itertools)文档地址:http://docs.python.org/2.7/library/itertools.html?highlight=itertools#itertools
def staritertools():
value=raw_input().strip()
while value!=‘‘:
for s in itertools.islice(value.split(),4,None):
#islice(iterable, [start,] stop [, step]) --> islice object
seq, [start,] stop [, step] |
elements from seq[start:stop:step] |
islice(‘ABCDEFG‘, 2, None) --> C D E F G |
itertools.islice(iterable, stop)
itertools.islice(iterable, start, stop[, step])
yield s
value=raw_input().strip()
当需要抽取位于流中特定位置数据时,可以使用itertools.islice
例如:可能需要使用记录特殊格式文件或者表现元数据(SOAP封套)封装数据流,islice可以看作在每行数据之上一个滑动窗口
这个方法可以提供在一个序列之上运行多个迭代器模型,如果提供第一次运行信息,就可以帮助我们再次基于这些数据运行
比如读取文件表头可以在运行一个处理之前提供特性信息
itertools.tee(iterable[, n=2])
def s(s,m=1):
a,b=itertools.tee(s)
return list(itertools.islice(a,m)),b
>>> s(‘sdfsdsdfsdfsdfsdsdfsdf‘,1)
([‘s‘], <itertools.tee object at 0x00000000027BDB88>)
>>> s(‘sdfsdsdfsdfsdfsdsdfsdf‘,10)
([‘s‘, ‘d‘, ‘f‘, ‘s‘, ‘d‘, ‘s‘, ‘d‘, ‘f‘, ‘s‘, ‘d‘], <itertools.tee object at 0x
0000000002979C48>)
>>>
对来自一个迭代器的重复元素进行分组,只要它们是相信的,还可以提供劬一个函数来执行元素比较,否则将采用标识符比较
Groupby一个应用实例是可以使用行程编码(RLE)来压缩数据,字符串中每组相信重复字符将替换成这个字符本身和重复数次,如果字符无重复,则使用1
def c(d):
return ((len(list(g)),n)for n,g in itertools.groupby(d))
def d(d):
return (size*car for size,car in d)
>>> list(c(‘get uuuuuuuuuuuuuuuuuuuuuuuup‘))
[(1, ‘g‘), (1, ‘e‘), (1, ‘t‘), (1, ‘ ‘), (24, ‘u‘), (1, ‘p‘)]
>>> lista=(c(‘get uuuuuuuuuuuuuuuuuuuuuuuup‘))
>>> ‘‘.join(d(lista))
‘get uuuuuuuuuuuuuuuuuuuuuuuup‘
装饰器@
论坛地址:http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html
特点:使函数或者方法封装(接收一个函数并返回增强版本一个函数)
使用场景可以将方法在定义首部将其定义为类方法或者静态方法
基本语法:
旧式装饰器语法
class WhatFor(object):
def it(cls):
print‘hello‘
it=classmethod(it)
def uncommon():
print ‘xx‘
uncommon=staticmethod(uncommon)
新式装饰器语法如下:
class W(object):
@classmethod
def it(cls):
print ‘helklo:%s‘%cls
@staticmethod
def u():
print‘i int float decimal str class if......‘
>>> a=W()
>>> a
<__main__.W object at 0x00000000025E92B0>
>>> dir(a)
[‘__class__‘, ‘__delattr__‘, ‘__dict__‘, ‘__doc__‘, ‘__format__‘, ‘__getattribut
e__‘, ‘__hash__‘, ‘__init__‘, ‘__module__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_e
x__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘, ‘_
_weakref__‘, ‘it‘, ‘u‘]
>>> a.it()
helklo:<class ‘__main__.W‘>
>>> a.u()
i int float decimal str class if......
>>>
如何自己编写装饰器
def my(f):
def _m(*a,**k):
#在调用实际函数之前做些填充工作
res=f(*a,**k)
#做完某些填充工作之后
return res
#返回子函数
return _m
结构
如果装饰器需要参数是,就必须使用第二级封装格式如下:
def m(a1,a2):
def _m(f):
def __m(*a,**k):
#在调用实际函数之前做些填充工作
res=f(*a,**k)
#做完某些填充工作之后
return res
#返回子函数
return __m
return _m
当@在模块第一次被读取时由解释器程序装入,所以它们使用必须受限于总体上可以应用@,如果@与方法的类或所增强的函数签名绑定,它应该被重构为常规可调用对象,在任何情况下,当@处理API时,一个好的方法是将它们聚集在一个易于维护模块中
@应该关注于所封闭的函数或者方法接收和返回参数,如果需要,应该尽可能限制其内省(introspection)工作,@包括参数检查,缓存,代理,上下文提供者!
参数检查:XML-RPC协议量种轻量级远程过程调用协议,通过HTTP上的XML来对调用进行编码,通常用于在简单客户-服务器代替SOAP
与SOAP不同(SOAP能够列出所有可调用函数页面,即wsdl)
Xml-rpc没有可用函数目录
# -*- coding: utf-8 -*-
__author__ = ‘Administrator‘
from itertools import izip
rpc_info = {}
def xmlrpc(in_=(), out=(type(None),)):
def _xmlrpc(function):
#register signature
func_name = function.func_name
rpc_info[func_name] = (in_, out)
def _check_types(elements, types):
"""Subfunction that checks the types."""
if len(elements) != len(types):
raise TypeError(‘argument count is wrong‘)
typed = enumerate(izip(elements, types))
for index, couple in typed:
arg, of_the_right_type = couple
if isinstance(arg, of_the_right_type):
continue
raise TypeError(‘arg #%d should be %s‘ % (index, of_the_right_type))
# encapsulate function
def __xmlrpc(*args):
# check input content
checkable_args = args[1:]
_check_types(checkable_args, in_)
# execute the function
res = function(*args)
# check output content
if not type(res) in (tuple, list):
checkable_res = (res,)
else:
checkable_res = res
_check_types(checkable_res, out)
return res
return __xmlrpc
return _xmlrpc
# example
class RPCView(object):
@xmlrpc((int, int))
def meth1(self, int1, int2):
print ‘received %d and %d‘ % (int1, int2)
@xmlrpc((str,), (int,))
def meth2(self, phrase):
print ‘received %s‘ % phrase
return 12
print rpc_info
my = RPCView()
my.meth1(1,2)
my.meth2(2)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。