PHP and Python学习

    xiaoxiao2022-06-29  51

    1PHP语言

    1.1使用范围

    web服务器 控制脚本 桌面程序

    1.2特点

    解释型语言:解释器php 适用环境:unix.linux,widows 支持mysql,db2,dbase,odbc,oracle等数据库 支持soap,snmp,pop3,smtp,com,corba等协议 关联站点: http://www.runoob.com/python/python-tutorial.html http://www.w3school.com.cn/index.html

    1.3基本语法

    大小写不敏感 语法与c类似

    "#! /usr/bin/php <?php print “hello world”; ?>"

    1.3.1变量

    $x,变量名前面加$ 动态语言,无需预先设置变量类型;

    1.3.2数组

    定义

    数组的关键字是”array” 用()将内容包括,元素之间用,分隔 Php中数组包括两个部分:关键字和数值 关键字是整数或者字符串 $array=array(5=>”one”,6=>”second”) 如果没有映射关系,默认关键字是下标,下标从0开始:$array=(1,3,4) 数组可以嵌套

    引用:

    $b=array[关键字]

    使用:

    新增:$b[新关键字]=值 修改:$b[原关键字]=值 清除:uset($b[关键字])或uset($b)清除所有 打印数组print_r($b)

    1.3.3运算符

    1.3.4控制

    条件

    if,else if(expr) { statement} else{ statement} 替换写法: if expr: elseif: endif switch switch expr{ case condition1: statemen1 ; break; }

    循环

    for;foreach,while for(start;condition;expr){ Statement; } foreach(组合 as 元素){ Statement }

    包括

    require,include;require_onceinclude_once

    1.4类

    class,public,private

    1.4.1属性

    属性定义赋值时必须是常数,不能是运算得到的

    class test { Public a=3; Private b=3; Public foo() }

    访问:

    $test=new test; $test->a; $test->foo(); 对于静态成员要用self::成员名来访问

    扩展:

    Class a extends B{ this->成员 }

    1.5函数

    定义

    函数名($a,$b...){ statement } 可以用func_nums_args,func_get_args,func_get_arg来获得可变参数

    2 Python

    2.1 使用范围

    web后台脚本 日常维护

    2.2 特点

    解释型语言:解释器python,动态数据类型,面向对象 适用环境:unix.linux,widows 支持mysql,db2,dbase,odbc,oracle等数据库 支持soap,snmp,pop3,smtp,com,corba等协议

    2.3 基本语法

    大小写敏感

    "#! /usr/bin/python print “hello world”

    语法与c类似,但是不用括号表示结构的边界,而是通过缩进来表示。

    2.3.1 注释:

    用’#’注释单条语句 用’’’来注释多条语句

    2.3.2 变量

    动态数据类型,无需预先设置变量类型;

    编码问题:

    ascii编码是7位bit,只能表示127种字符, unicode编码是2个byte,将世界的语言编码都统一了,比如 u"[\u4e00-\u9fa5]"#中文 u'[\u3040-\u409f]#日文 片假名 u'[\uac00-\ud7ff]#韩文 在python中用u’xxx’表示unicode,xxx可以是直接输入的字符或者象上面用\u数字来表示. utf8是可变长编码,用1-6个字节来表示字符.通常中文用3个字节来表示. 在内存中一般用unicode来表示字符,在存储和数据传输时通常采用utf8编码以节省空间和传输时间. 对于字符串类型变量都有encode和decode函数,encode函数是将unicode转换成想要的字符 比如str.encode('utf8'), decode是将其他类型字符转换成unicode字符,比如将文件存储的utf8数据转换成unicode数据, str.decode('utf8'). 此外,还有codecs模块,可以用来做转换工作. import codecs with codecs.open(xxxfilename,’rb’,’utf8’) as f   str=f.read() 就可以避免在str中再做转换了.

    codecs支持的编码如下:

    编码别名支持语言ascii646, us-asciiEnglishbig5big5-tw, csbig5Traditional Chinesebig5hkscsbig5-hkscs, hkscsTraditional Chinesecp037IBM037, IBM039Englishcp424EBCDIC-CP-HE, IBM424Hebrewcp437437, IBM437Englishcp500EBCDIC-CP-BE, EBCDIC-CP-CH, IBM500Western Europecp720Arabiccp737Greekcp775IBM775Baltic languagescp850850, IBM850Western Europecp852852, IBM852Central and Eastern Europecp855855, IBM855Bulgarian, Byelorussian, Macedonian, Russian, Serbiancp856Hebrewcp857857, IBM857Turkishcp858858, IBM858Western Europecp860860, IBM860Portuguesecp861861, CP-IS, IBM861Icelandiccp862862, IBM862Hebrewcp863863, IBM863Canadiancp864IBM864Arabiccp865865, IBM865Danish, Norwegiancp866866, IBM866Russiancp869869, CP-GR, IBM869Greekcp874Thaicp875Greekcp932932, ms932, mskanji, ms-kanjiJapanesecp949949, ms949, uhcKoreancp950950, ms950Traditional Chinesecp1006cp1026ibm1026Turkishcp1140ibm1140Western Europecp1250windows-1250Central and Eastern Europecp1251windows-1251Bulgarian, Byelorussian, Macedonian, Russian, Serbiancp1252windows-1252Western Europecp1253windows-1253Greekcp1254windows-1254Turkishcp1255windows-1255Hebrewcp1256windows-1256Arabiccp1257windows-1257Baltic languagescp1258windows-1258Vietnameseeuc_jpeucjp, ujis, u-jisJapaneseeuc_jis_2004jisx0213, eucjis2004Japaneseeuc_jisx0213eucjisx0213Japaneseeuc_kreuckr, korean, ksc5601, ks_c-5601, ks_c-5601-1987, ksx1001, ks_x-1001Koreangb2312chinese, csiso58gb231280, euc- cn, euccn, eucgb2312-cn, gb2312-1980, gb2312-80, iso- ir-58Simplified Chinesegbk936, cp936, ms936Unified Chinesegb18030gb18030-2000Unified Chinesehzhzgb, hz-gb, hz-gb-2312Simplified Chineseiso2022_jpcsiso2022jp, iso2022jp, iso-2022-jpJapaneseiso2022_jp_1iso2022jp-1, iso-2022-jp-1Japaneseiso2022_jp_2iso2022jp-2, iso-2022-jp-2Japanese, Korean, Simplified Chinese, Western Europe, Greekiso2022_jp_2004iso2022jp-2004, iso-2022-jp-2004Japaneseiso2022_jp_3iso2022jp-3, iso-2022-jp-3Japaneseiso2022_jp_extiso2022jp-ext, iso-2022-jp-extJapaneseiso2022_krcsiso2022kr, iso2022kr, iso-2022-krKoreanlatin_1iso-8859-1, iso8859-1, 8859, cp819, latin, latin1, L1West Europeiso8859_2iso-8859-2, latin2, L2Central and Eastern Europeiso8859_3iso-8859-3, latin3, L3Esperanto, Malteseiso8859_4iso-8859-4, latin4, L4Baltic languagesiso8859_5iso-8859-5, cyrillicBulgarian, Byelorussian, Macedonian, Russian, Serbianiso8859_6iso-8859-6, arabicArabiciso8859_7iso-8859-7, greek, greek8Greekiso8859_8iso-8859-8, hebrewHebrewiso8859_9iso-8859-9, latin5, L5Turkishiso8859_10iso-8859-10, latin6, L6Nordic languagesiso8859_11iso-8859-11, thaiThai languagesiso8859_13iso-8859-13, latin7, L7Baltic languagesiso8859_14iso-8859-14, latin8, L8Celtic languagesiso8859_15iso-8859-15, latin9, L9Western Europeiso8859_16iso-8859-16, latin10, L10South-Eastern Europejohabcp1361, ms1361Koreankoi8_rRussiankoi8_uUkrainianmac_cyrillicmaccyrillicBulgarian, Byelorussian, Macedonian, Russian, Serbianmac_greekmacgreekGreekmac_icelandmacicelandIcelandicmac_latin2maclatin2, maccentraleuropeCentral and Eastern Europemac_romanmacromanWestern Europemac_turkishmacturkishTurkishptcp154csptcp154, pt154, cp154, cyrillic-asianKazakhshift_jiscsshiftjis, shiftjis, sjis, s_jisJapaneseshift_jis_2004shiftjis2004, sjis_2004, sjis2004Japaneseshift_jisx0213shiftjisx0213, sjisx0213, s_jisx0213Japaneseutf_32U32, utf32all languagesutf_32_beUTF-32BEall languagesutf_32_leUTF-32LEall languagesutf_16U16,utf16all languagesutf_16_beUTF-16BEall languages (BMP only)utf_16_leUTF-16LEall languages (BMP only)utf_7U7, unicode-1-1-utf-7all languagesutf_8U8, UTF, utf8all languagesutf_8_sigall languages

    base64编码

    为了使用可见字符传输二进制数据,将二进制数据每3个字节分成一组,将这3个字节再分成4组,每组有6个bit,而2^6=64,这样就可以用可见字符来表示二进制数据了.如果二进制数据最后有1个或2个多余的字节,则用\x0来补足,同时,在编码末尾补充一个或二个=,表示补充的字节数.

    模块有base64

    import base64 base64.b64encode(‘’)和base64.b64decode(‘’)

    base64常用于url,cookie,少量的二进制文件传输(电子邮件)

    数据转换

    为了将字符串和二进制数值相互转换

    import struct struct.pack(‘转换格式’,数据字符串) #将数据字符串转换成二进制数据 struct.unpack(‘转换格式’,二进制字符串) #将二进制字符串转换成数据 例如:struct.pack(‘h’,1024) #将1024按照2字节的小头序转换(低字节在前) 输出:/x00/x04 struct(‘>h’,1024) #将1024按照2字节的大头序(网络次序)转换(高字节在前) 输出:/x04/0x00 struct.unpack(‘h’,’/x00/x04’) 输出:1024 转换字符:i表示按照4字节转换整数,h表示按照2字节转换整数,>表示按照大头序,不带>表示按照小头序转换. FormatC TypePython typeStandard sizeNotesccharchar11bsignedchar integer1(3)Bunsigned charinteger1(3)?Boolbool1(1)hshortinteger2(3)Hunsigned shortinteger2(3)iintinteger4(3)Iunsigned intinteger4(3)llonginteger4(3)Lunsigned longinteger4(3)qlong longinteger8(2), (3)Qunsigned long longinteger8(2), (3)ffloatfloat4(4)ddoublefloat8(4)schar[]stringpchar[]stringPvoid *integer(5), (3)

    2.3.3 数组

    Python中的数组有两种:一种是可变的叫list用[]来表示; 一种是不可变的叫tuple,用()来表示,不像php需要有关键字来标识.

    可变的数组:

    Array=[1,3]; Array.append(3);在最后一个位置添加 Array.insert(1,4);在第二个位置插入 Array.pop();删除最后一个 Array.pop(1);删除第二个位置的数 数组的数从位置0开始,-1表示最后一个.-2表示倒数第二个;

    不可变数组:

    不可变指的是该索引所指向的数不变,如果数组中包括可变数组,则可变数组的内容是可以变的, 但是在不可变数组中指向该可变数组的指向并没有变; Array=(1,3,[4,5]); 需要注意的是在不可变数组中如果只有一个数也要加上逗号以免歧义

    字典

    dict实际上是一种映射: dict={key:value,key2:value2} dict=['a':1,'b':2];可以使用dict[key]来访问,用pop来删除; 可以使用get方法来判断是否存在元素; 需要注意的是:key是唯一区分数组元素的标识,所以重复的key以后面的为准. Set表示关键字组合: 与dict不同的是里面不存value 创建set需要提供一个list例如set=set([1,2]). 可以使用add(key),remove(key)来操作; 但是如果添加重复的key不会有效果; 可以从数组中切一块下来[起始位置:终点位置] 注意:实际操作中如果将数组赋值给另一个数组,则这两个数组指向同一个地址,而不是数值相等.

    列表生成式:

    a=[x*x for x in range(10) if x%2==0]

    生成器:

    如果一个函数中有yield关键字,则这个函数就成为一个生成器,不是直接打印而是返回一个list; #! /usr/bin/python def yang(): u=[1] while True: yield u u.append(0) u=[u[i]+u[i-1] for i in range(len(u))] j=0 for i in yang(): print i j=j+1 if j==10: break 杨辉三角形

    数组进阶collections

    命名tuple tuple是用下标来获取元素值,不太直观,可以用命名tuple来获取元素.如此比定义一个类方便. from collections import namedtuple namedtuple(tuple名,[元素名]) 例如:point=namedtuple(“point”,[‘x’,’y’] point(1,2) point.x point.y

    deque

    为了方便插入删除list中的元素. from collections import deque d=deque([‘a’,’b’]) d.appendleft(‘x’)#在list头加入元素,不像list一样需要用下标 d.popleft()#在头部删除元素 d.append()#在尾部加入元素 d.pop()#在尾部删除元素

    defaultdict

    defaultdict用来当引用dict中不存在的元素时,返回一个默认值 import defaultdict from collections dd=defaultdict(lambda:’N/A’) dd[‘a’]=1 dd[‘a’] dd[‘b’]#返回N/A

    OrderedDict

    dict插入时key是无序的,采用OrderedDict使得key按照插入顺序来排列 from collections import OrderedDict od=OrderedDict([‘a’:1,’b’:2,’c’:3])

    Counter

    counter用来根据key来计算key出现的次数 from collections import Counter ch=Counter() for i in str:   ch[i]=ch[i]+1 counter返回的是一个dict{‘xx’:xx,’xx’:xx...}#注意,访问dict对象是通过key来访问的xxdict.[关键字] Counter构造函数输入的是一个list,Counter.most_common(排名前几位)返回的是排名前几位的list对象. 例子:搜索文章中排名前10位的单词 from collections import Counter import re words=re.findall(r’\w+’,open(‘test.py’,’r’).read()) ch=Counter(words).most_common(10) for i in range(len(ch)):   print ch[i]

    2.3.4 运算符

    注意下面表达式的区别:

    a,b=b,a+b#假如a,b开始为1,2则执行后,a,b为2,3;在赋值之前a,b变量值是原来的值. a=b b=a+b

    执行前a,b为1,2.执行后a,b为2,4.区别就在于后者执行第一条语句后a的值就发生的变化,而上面的表达式执行给b赋值的语句时,a的值没有发生变化.

    2.3.5 控制

    与c类似,但是没有括号来表示边界而是通过缩进: 条件

    if expr : statement else statement

    循环

    for 元素 in 组合 statement 组合是一个list.或者用range来生成一个范围;range([start],stop,[step]) while expr: statement

    2.4 类

    class,public,private class 类名(继承类名) __init__(self,其他参数): self.xx=xx

    构造函数,self是必须的,指向类本身

    获取类信息:

    Type:type(实例名) dir:dir(实例名) isinstance(实例名,类名)

    实例属性优先于类属性,如果实例属性与类属性相同,将覆盖类属性.实例属性可以动态增减.del 实例.属性

    2.4.1 动态类

    类在实例化后可以用实例.成员的方法来改变属性和方法,但是如果仅仅是对实例做上面的操作,仅仅是改变实例的成员.如果需要改变该类的成员,就要把实例改成类. 同时,如果在类的定义中加入slot限制,可以限制动态添加成员,只能动态添加在slot中的成员.

    from types import MethodType class student(object):        __slots__=('name','age','add_fun') s=student(); s.name='han' s.age=32 print s.name,s.age def add_fun(self,xxx): print 'hello,add fun' s.add_fun=MethodType(add_fun,s) s.add_fun('a') s2=student() student.add_fun=add_fun s2.add_fun('a') getattr getattr可以在类中没有需要的成员时,返回一个默认的成员值        class attr(object):         def __init__(self,path=''):         self._path=path         def __str__(self):         return self._path         def __getattr__(self,x):         return attr("%s/%s"%(self._path,x))        print attr().a.b.c        Run:        a/b/c

    2.4.2 元类:

    元类是为了创建类结构,是类结构的模板.一般我们是静态的创建类结构,然后根据类结构创建类实例.但是,为了能够动态的创建类结构,引进了元类的概念.

    class listmetaclass(type): def __new__(cls,name,bases,attr): attr['add']=lambda self,value:self.append(value) return type.__new__(cls,name,bases,attr) class MyList(list): __metaclass__=listmetaclass#指出该类为元类 l=MyList() l.add(1) print l

    在这个例子中,为list类增加了一个属性add.

    2.4.3 使用property

    使用property的目的是简化类函数的定义,不要对类成员使用get,set方法

    class screen: @property def width(self):#相当于调用get方法 return self._width @width.setter#相当于调用set方法 def width(self,value): self._width=value s=screen() s.width=19 print s.width

    2.4.4 自定义类:

    为了实现类似int的用法,比如可以循环,数组,需要自定义类

    class screen(object): def __init__(self,a=0): self.a=a self.b=0 def __str__(self): return 'screen class attrib a is %s'%self.a def __iter(self): return self def __next(self): self.a=self.a+1 if self.a>100: raise StopIteration return self.a def __getitem__(self,n): self.a=n+self.a if self.a>100: raise StopIteration return self.a s=screen() for i in screen(): print i

    从实例来看,为了使screen类能够构成list,必须定义iter,getitem函数,next可以不定义.而且,函数的下划线必须是程序中的形式.

    2.5 调试

    2.5.1 异常捕获:

    Try…except…finally

    try: l=MyList() l.add(1) print (l) except ValueError : print ('SrandardError') finally: print ('finally')

    2.5.2 Log

    import logging#引入loggng logging.basicConfig(level=logging.INFO)#设置logging级别debug,info,warning,error class listmetaclass(type): def __new__(cls,name,bases,attr): logging.info('new:') attr['add']=lambda self,value:self.append(value) return type.__new__(cls,name,bases,attr)

    2.5.3 单元调试

    编写单元模块测试函数

    import unittest from test import MyList class TestMyList(unittest.TestCase): def setUp(self):#表示在测试方法前调用的函数 print('\nstart') def tearDown(self):#表示在测试方法后调用的函数 print ('\nteardown') def test_init(self):#表示用于测试类成员的函数,名字前面是test d=MyList() self.assertEquals(d[0],1) if __name__=='__main__': unittest.main() 执行python mytest.py Run: start E teardown ====================================================================== ERROR: test_init (__main__.TestMyList) ---------------------------------------------------------------------- Traceback (most recent call last): File "mytest.py", line 10, in test_init self.assertEquals(d[0],1) IndexError: list index out of range ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1)

    2.6 函数

    2.6.1 函数定义

    def 函数名(参数): statement 参数可以是单个变量,默认参数,list或tuple,或者是dict 如果是list或tuple,参数前加* 如果是dict,参数前加** Dict参数是类似a=xx,b=xx形式的

    2.6.2 引入其他模块:

    import xx from 库名 import 模块名 安装python模块可以用:pip install 库名,或者easy_install 库名 函数指针: f=abs() f(-10) 10,相当于将函数指针赋给了一个变量;

    2.6.3 map和reduce函数

    map和reduce函数用来将一个函数作用在一组变量上,参数都是一个函数和一个组合。

    map函数的函数参数只需要一个变量:

    def fun(x): return x*x list1=map(fun,[1,2,3]) print list1 run: [1,4,9]

    reduce函数的函数参数需要两个变量,用来将2个变量合成一个变量以便于与下一个变量继续计算

    def fun(x,y):        return x+y a=reduce(fun,[1,2,4]) run: 7

    2.6.4 filter 函数

    filter函数从一个组合中筛选出符合条件的组合,需要两个参数,一个是组合,一个是筛选函数:

    def f(x): return x%2==0 l=filter(f,range(10)) print l Run:[0, 2, 4, 6, 8]

    2.6.5 sorted函数:

    sorted函数用来对组合排序,是一个抽象函数,需要两个参数数,一个是组合一个是排序函数

    def f(x): return x[1] str=[('a',5),('b',2),('c',3),('d',4)] str2=sorted(str,key=f) print str2 Run: [('b', 2), ('c', 3), ('d', 4), ('a', 5)]

    2.6.6 返回函数

    返回函数是指在一个函数中再定义一个函数,然后将这个函数赋值给一个变量,如果直接调用这个函数,将不会产生结果,直到用这个变量被调用.内部的函数接受输入的参数.

    def f(*args): def inter_fun(): ax=0 for i in args ax=ax+i return ax return inter_fun s=f(1,2,3) #此时不会返回结果 s() #此时才会返回结果 相当于是函数指针. Run:6

    2.6.7 匿名函數:

    有时为了不显式定义函数,可以采用匿名函数形式

    Y=lambda x:x*x Y(2)

    2.6.8 装饰函数:

    装饰函数的作用是给一个函数添加新方法

    def f(func): def wrapper_fun(*args,**kw): print “decorator %s”%func.__name__ func(*args,**kw) return wrapper_fun @f def f(): print ‘this is f’ f() run decorator f this is f 关键字:@修饰符,wrapper 如果需要传入参数给f,需要再包一层 def f(para): def decorator_fun(f): def wrapper_fun(*args,**kw): print “%s decorator %s”%para,func.__name__ f(*args,**kw) rerurn wrapper_fun return decorator_fun @f(‘sss’) def f(): print ‘this is f’ f() run aaa decorator f this is f

    2.6.9 文件函数

    f=open(路径,打开方式) 打开方式可以是’r’,’w’,’rb’,’wb’ f.read([size])[.decode(编码方式)],比如f.read().decode(‘gbk’) read默认是读入所有内容,如果文件太大,则可以给size参数 readlines 返回以每行为元素的list;可以for i in f.readlines(); 如果要编码还可以使用module:codecs,则要import codecs codecs.open() f.close()#关闭文件 如果不想每次都关闭文件可以用: with open as f f.xxx

    2.6.10 os模块:

    os模块中封装了系统命令

    import os os.name#操作系统名字 os.uname()#操作系统详细信息 os.environ#环境参数 os.getenv(环境变量参数)#例如os.getenv(‘path’) os.path.abspath(目录)#获得目录的绝对路径 os.path.join(目录1,目录2)#将目录合并,注意不要用字符串合并,而要用join, 否则可能由于操作系统不同而变化. os.mkdir(xxx) os.rmdir(xxx) os.path.split(xxx)#将路径分解成目录和文件名 os.path.splitext(xxx)#分解扩展文件名 os.rename(xxx,xxx)#改名 os.remove(xxx)#删除文件 os.listdir(xxx)#列出文件 os.path.isdir(xxx)#是否是文件夹 shutil模块中有copyfile()函数

    序列化:

    就是将dict变成字符流,serialization

    python中的序列化方法是cpickle或pickle,还有就是json(java script object) pickle方法只能用在python中,而json方法可以跨平台 dict_str=dict(name=’a’,age=20) try :        import cpickle: expect importerror:        import pickle p=pickle.dumps(dict_str)#将dict序列化 pickle.loads(p)#反序列化,将序列化流反成dict对象 with open(‘dump.txt’,’wb’) as f:        pickle.dump(dict_str,f) with open(‘dump.txt’,’rb’) as f        pickle.load(f)#从文件中反序列化 Import json j=json.dumps(dict_str) json.loads(j) with open(‘dump.txt’,’wb’) as f:#将dict序列化后输出到文件中        json.dump(dict_str,f) with open(‘dump.txt’,’rb’) as f        json.load(f)#从文件中反序列化 Json对象的{}对应python的dict Json对象的[]对应python的list 上面讲的的是对dict对象进行序列化,如果需要对类进行序列化,需要对类进行加工. class strudent:        def __init__(self,name,age,scope):            self._name=name            self._age=age            self.scope=scope def student2dict(std):#需要将类转换成json的dict        return{‘name’:std.name,’age’:std.age,’scope’:std.scope} s=student(‘bog’,28,1) import json json.dumps(s,default=student2dict) 也可以不写上面的函数,由于类中默认有一个dict所以可以写成 json.dumps(s,default=lambda obj:obj.__dict__) 为了反序列化,同样的需要将dict对象变成class对象 def dict2student(dict):        return student(d[‘name’],d[‘age’],d[‘scope’]) josn_str={‘name’:’bog’,’age’:20,’scope’:18} json.loads(json_str,object_hook=dict2student)

    2.6.11 多进程,多线程,分布式进程

    Python中的多进程可以用fork,Process来实现,fork方法是unix下的方法,Porcess是跨平台的方法

    import os pid=os.fork() if pid==0:        print (‘i\’m a child process’) else:        print (‘i\’m a parent process’) 或者: from multiprocessing import Process import os def run_proc(name):#指定进程函数        print (‘run a child process%s’%name) if __name__=’__main__’:        print (‘parent process %d is run’%os.getpid())        p=Process(target=run_proc,args=(‘test’,))#注册进程        print (‘process will start’)        p.start()#启动进程        p.join()#终止进程        print (‘end process’)

    线程:

    与process类似

    import time,threading def loop():     for i in range(20):         time.sleep()         print (‘in thread’) t=threading.thread(target=loop) t.start() t.join()

    分布式进程

    分布式进程就是将进程分配到多个计算机中(工作者),由一个管理者通过网络管理任务分配. 相关类有:Queue,BaseManager 实现思想:管理者创建队列,分别是发送队列和结果队列.管理者创建队列管理者注册这两个队列并建立网络服务,向发送队列中输出任务. 工作者负责执行任务,主要步骤是工作者也创建一个队列管理者,注册队列,队列名与管理者注册的队列名一致,然后与管理者建立连接,接收队列,执行队列中的任务.

    Taskmanager.py

    #test muliti processing #first:type 'python taskmanager.py',then this prog will run #second:type in other terminal 'python taskworker.py' import random,time,Queue from multiprocessing.managers import BaseManager task_queue=Queue.Queue() result_queue=Queue.Queue() class QueueManager(BaseManager): pass QueueManager.register('get_task_queue',callable=lambda :task_queue) QueueManager.register('get_result_queue',callable=lambda:result_queue) manager=QueueManager(address=('',5000),authkey='abc') manager.start() task=manager.get_task_queue() result=manager.get_result_queue() for i in range(10): n=random.randint(0,1000) print('put task %s'%n) task.put(n) print ('Try get result...') for i in range(10): r=result.get(timeout=10) print ('Result:%s'%r) manager.shutdown()

    Taskworker.py

    import time,sys ,Queue from multiprocessing.managers import BaseManager class QueueManager(BaseManager): pass QueueManager.register('get_task_queue') QueueManager.register('get_result_queue') server_add='127.0.0.1' print ('connect to server:%s'%server_add) m=QueueManager(address=(server_add,5000),authkey='abc') m.connect() task=m.get_task_queue() result=m.get_result_queue() while True: if task.empty():break try: n=task.get(timeout=1) print ('run task %d*%d...'%(n,n)) r='%d*%d=%d'%(n,n,n*n) time.sleep(1) result.put(r) except Queue.Empty: print('task queue is empty') print ('worker is end') Run: 管理者:     python taskmanager.py     put task 778     put task 405     put task 561     put task 760     put task 911     put task 583     put task 370     put task 309     put task 383     put task 699     Try get result...     Result:778*778=605284     Result:405*405=164025     Result:561*561=314721     Result:760*760=577600     Result:911*911=829921     Result:583*583=339889     Result:370*370=136900     Result:309*309=95481     Result:383*383=146689     Result:699*699=488601 工作者:     python taskworker.py     connect to server:127.0.0.1     run task 778*778...     run task 405*405...     run task 561*561...     run task 760*760...     run task 911*911...     run task 583*583...     run task 370*370...     run task 309*309...     run task 383*383...     run task 699*699...     worker is end

    2.6.12 正则表达式:

    正则表达式用来匹配字符,最简单的是用’*’来匹配任意字符,用’?’来匹配一个字符. 其余的有以下规则: 不加转义符,如‘a’,表示要匹配a字符 加转义符:’\d’:匹配数字 ‘\w’:匹配字符字符和数字 ‘\s’:匹配一个空格,’\s+’:至少一个空格 范围匹配: []:用来匹配一个范围,如[a-z],如果后面加+,则表示至少匹配一个这样的字符 ^表示行开始,比如^\d表示必须以数字开始 $表示行结束,比如\d$表示必须以数字结束 {}:表示需要匹配的个数,比如\d{3}表示匹配3个数字,\d{3,8}表示匹配3到8个数字. a|b:表示条件或,比如[p|p]ython,表示匹配python或python 注意有些特殊字符需要转义:如\-,\_等 python中的正则表达式使用: 在python中\也是转义符,所以要是定义成字符串时,对于用于转义的\也要转义,就要定义成\\, 为了方便在转义符之前加上r’xxx’,就不需要写成\\形式了 python中使用转义符需要import re,调用函数是match import re re.match(r’^\d{3}\-\d{3,8}$’,’010-12345’) 用来匹配电话号码 match如果成功则返回一个match对象,否则返回none 分组: 通过在正则表达式中使用()可以将结果分组,用group(x)来提取,0表示原字符 比如上面例子中需要提取区位号码和电话号码 m=re.match(r’^(\d{3})\-(\d{3,8}$)’,’010-12345’) m.group(1)是010 m.group(2)是12345 切分字符串: 为了从字符串中提取需要的内容,常常需要切分字符串,这时使用正则表达式可以起到很大作用. 比如re.split(r’\s’+,’a b c’) 输出为[‘a’,’b’,’c’] >>> re.split(r'[\s,;]+','a b ; , c') ['a', 'b', 'c'] 将空格,逗号,分号都除掉了 匹配中文: re_words=re.compile(u"[\u4e00-\u9fa5]")#中文 m=re_words.search(s,0) print m print m.group() word=re.findall(re_words,s) 上面的程序曾经出现没有找到匹配中文的情况,是由于字符串编码没有采用unicode.

    2.6.13 hashlib

    用来计算散列值

    import hashlib md5=hashlib.md5() md5.update(‘str’) md5.hexdigest()#返回128位的数据 sha1=hashlib.sha1()#计算160位的sha1数据

    2.6.14 itertools

    itertools可以构造一个可用于循环的数据集合,在构造时并不存在,只有在循环的时候才存在.

    import itertools n=itertools.count(x)#构造一个以x为起点的无限增长的数 for i in n:        print i 输出:无限长的数 repeat(x)#重复 cycle(‘xxx’)#循环 groupby(‘xxx’[,分组函数])#将内容按照关键字分组,相同内容分一组 返回key和group 例如: m=itertools.groupby(‘aaabbbccc’,lambda x:x.upper()) for key,group in m:        print key,list[group] 返回: a ['a', 'a', 'a'] b ['b', 'b', 'b'] c ['c', 'c', 'c'] takewhile(条件函数,构造队列) 例如: n=itertools.count(1) ns=itertools.takewhile(lambda x:x<10,n) chain#将两个组联合 例如: n=itertools.chain(‘abc’,’xyz’) imap: imap将两个队列按照公式组合 例如: n=itertools.imap(lambda x,y:x*y,[2,3,5],itertools.count(3)) for i in n:        print i 两个队列如果不等长,以较短的为算.

    2.6.15 解析xml

    xml解析有两种方法,dom和sax.前者将文件一次读入内存,后者按照流来处理 用sax来处理首先定义一个类,定义以下函数 startelement endelement characterdata 然后引入parsercreate,将上面的函数赋给parsercreate,然后调用parser函数就可以解析xml了.

    例如:

    from xml.parsers.expat import ParserCreate class DefaultSaxHandler(object): def start_element(self, name, attrs): print('sax:start_element: %s, attrs: %s' % (name, str(attrs))) def end_element(self, name): print('sax:end_element: %s' % name) def char_data(self, text): print('sax:char_data: %s' % text) xml = r'''<?xml version="1.0"?> <ol> <li><a href="/python">Python</a></li> <li><a href="/ruby">Ruby</a></li> </ol> ''' handler = DefaultSaxHandler() parser = ParserCreate() parser.returns_unicode = True parser.StartElementHandler = handler.start_element parser.EndElementHandler = handler.end_element parser.CharacterDataHandler = handler.char_data parser.Parse(xml) 输出: sax:start_element: ol, attrs: {} sax:char_data: sax:char_data: sax:start_element: li, attrs: {} sax:start_element: a, attrs: {u'href': u'/python'} sax:char_data: Python sax:end_element: a sax:end_element: li sax:char_data: sax:char_data: sax:start_element: li, attrs: {} sax:start_element: a, attrs: {u'href': u'/ruby'} sax:char_data: Ruby sax:end_element: a sax:end_element: li sax:char_data: sax:end_element: ol

    2.6.16 解析html

    解析html首先引入python中已经定义好的htmlparser 然后从html中派生类,并定义自己想要处理的函数 然后调用feed函数就可以处理html了. 调用feed函数可以不一次性输入全部html. 例子:

    from HTMLParser import HTMLParser from htmlentitydefs import name2codepoint class MyHTMLParser(HTMLParser): def handle_starttag(self, tag, attrs): print('tag:<%s>' % tag) def handle_endtag(self, tag): print('endtag:</%s>' % tag) def handle_startendtag(self, tag, attrs): print('starttag:<%s/>' % tag) def handle_data(self, data): print('data:%s'
    转载请注明原文地址: https://ju.6miu.com/read-1125456.html

    最新回复(0)