首发于 python学习
python3最全知识点,从入门到开车就是这么简单(建议收藏)

python3最全知识点,从入门到开车就是这么简单(建议收藏)

前言:

此文是自己学习python过程中的笔记和总结.

适合有语言基础的人快速了解python3和没基础的作为学习的大纲

了解学习的方向、知识点;笔记是从多本书和视频上学习后的整合版。

(一)初识python

1、一般文件以.py为格式;用#作注释.

2、一般对象不用特别声明,python会自动识别;一个对象也可以重新绑定到不同数据类型,因为python采用的是动态类型机制;但对已经声明过的对象则不能改变。

3、输出print("a"),在python控制台中也可以直接用这个对象名称,就会打印出来,用print打印多个字符串可用逗号连接,想将多个print打印在同一行,可以print后加上end=参数(例:print(x,end=" "),会以空格分隔)。输入input()

4、字符串可以用双引号或者单引号封装;

5、一个字符串可以通过[]来提取序列中的某一项;"abcd"[1]=="b";

6、len()会返回一个元组的长度;

7、元组的元素追加append,x.append("more");或者list.append(x,"more");元组也可以通过[]提取组内的某一个元素;

8、python语句结尾可不用标点符号,两个语句之间也可用分号分隔.

9、代码中的缩进排版方式是会影响程序的运行结果的!!!而且是非常非常重要...

10、内置打开文件函数open()返回一个文件对象(如果是文本文件,则类型为

io.TestIOWrapper),函数有一个必须参数(文件名,可包含路径)和6个可选参数。

常用格式:fin=open(filename,encoding="utf8") #for reading text

fout=open(filename,"w",encoding="utf8")

#for writing text(如果参数是"a"则是以追加形式写入文件中)

写入数据时用fout.write(string)。

从文件里读取到内容的格式是str,被写入的内容也须是str格式的对象。

11、随机数需导入random模块,后用:

x=random.randint(1,6) #产生给定范围的随机数y=random.choice(["appel","cherry","a","b"]) #在给定选择项中随机选择一项。
z=random.sample(iterable,limit);iterable为序列类,limit表示生成的最大数量,
且limit<=len(iterable)。因为生成的随机序列中iterable中的每个项最多出现一次。
其结果z为一个list。

12、将全大写字母表示的标识符看作常量是python的一个约定。

13、对于不了解的函数可用help()命令来看看函数的说明,可用dir()模块名来查看模块内的所有函数名。

14、如果要将一个命令写在两行,可以在第一行的末尾加上转义字符 \ 即可。

(二)逻辑操作符:

1、身份操作符(is,is not):用于判断两个对象的引用对象是否指向相同的对象,返回bool值.否定比较可以用is not;

2、比较操作符(<,>,<=,>=,==,!=):因为python使用Unicode编码表示字符串,对包含非ASCII字符的字符串比较更微妙和复杂.在python较有特点的就是可以进行结链比较: a=3,1<a<4(True);

3、成员操作符(in,not in):用于判断一个元素是否存在于一个元组或者集合中,返回bool值.

4、逻辑运算符(and,or,not):and(&)结果为and后边元素结果,or(|)为前边元素结果.not返回bool值,将原值反转.

在python中预定义为常量False的bool表达式、特殊对象None、空序列或集合、值为0的数值型数据项的bool结果为False,其他的都为True.

追加的还有:^(xor),<<左移,>>右移,~反转。

(三)算术操作符:

+、-、*、/、+=、*=,

对于后两种增强赋值操作符的对象必须是iterable.

对于列表进行扩展需对欲增加元素用[]包围。

//除取整,%取余,**(pow())幂,abs()返回绝对值,divmod(x,y)
以二元组形式返回
x/y所得商和余数(两个整数),
round(x,n)返回浮点数x四舍五入得到的整数(如果n有值,则返回相应位数的浮点数)

(四)控制流语句:

suite: 指一条或多条语句组成的序列。

1、if...else语句:

if boolean_expression1:suite1;
elif boolean_expression2: suite2;

else:... (注意有冒号,如果需要考虑某个特定情况但又不需要对它进行处理,那么就可以使用pass作为该分支的suite,pass是一个空语句。)

2、while语句:

while boolean_expression:suite

通过break、continue对循环进行控制,

break跳出循环,continue结束当前循环,

从新开始新的一轮循环;函数中的return也可以达到break的作用,而且都可以用于for语句

3、for...in语句:

for variable in iterable: suite

4、基本异常处理语句:

try: try_suite; except exception1 as variable1:exception_suite1

出现异常跳出的是整个函数,而不是整个程序。

(五)函数:

def functionName(arguments):suite

下面请看详细内容:

基础篇

一:Python3 常用数据类型语法

1、int类型

int类型的数据是没有长度限制的,它的最大长度只与计算机的内存有关。

bin(i)      返回二进制表示结果,
hex(i)      十六进制,
int(i)       整数(如果x是浮点数就会返回其整数部分,
oct(i)      八进制,
int(s,base)将字符串转换为整数.幂可以用**实现(10**5,2**4).内置的float与str类型都支持到整数的转换。
chr()       将数字转换成字符,
ord()       将字符转换成ASCII码;
round()   函数对值进行四舍五入。整数和浮点数相加结果是浮点型。

2、简单比较两个float是否相等

def equal_float(a,b):
return abs(a-b)<=sys.float_info.epsilon

3、复数

复数的表示需在虚部后加一个j,如z=3.5+2j.

其中实部和虚部可分别用z.real,z.imag取得。

专用函数z.conjugate()可以反转虚部的符号。

4、Decimal

特点:精度高,但计算速度比float慢,使用前需引进模块。

 a=decimal.Decimal(5555)或a=decimal.Decimal("555.555")

5、字符串

对字符串内使用的单引号或者双引号,如果与最外层的相同则需要进行转义,如果不同则可以直接使用。

字符串转义:

\newline 忽略换行,

\\ 反斜杠,

\' 单引号,

\" 双引号,

\a 蜂鸣,

\b 退格,

\f 走纸,

\n 换行,

\r 回车,

\t 制表符。

6、负索引

即从-1开始从末尾倒数。

7、字符串的分片操作(seq[start:end];seq[start:end:step]

seq[start:end] ,表示两个位置之间的字符(区间为左闭右开,即[start,end)),无start则默认为0,无end则默认为len(seq),

seq[:] 表示整个字符串。

字符串的追加可用+=,但并不是特别高效,连接大量字符串可用seq.join()。

"xx".join(seq)则可以将xx依次插入每两个seq元素之间,形成一个str。
seq[star:end:step]与前一种类似,但是step不能为空,且必须大于0,即步长。

8、reversed()反转一个集合内元素的排列顺序。

9、字符查找(index(),find())

find()找到目标时返回该字符在字符串中的索引位置,

没找到则返回-1;index() 找到时也返回索引位置,没找到则产生一个ValueError异常。

函数前边加r的(rfind(),rindex())表示逆序开始查找。

find()、index都可接受至多两个可选参数(起点、终点):

    str.find("m",6)=str[6:].find("m")
    str.find("m",2,5)=str[2:5].find("m")

类似的函数还有: str.count(),str.endswith(),str.startswith()。

10、字符串分割partition(),rpartition(),split(),strip()

patition()将字符串分割为三段:关键字前,关键字,关键字后.
split()将字符串以关键字为分割点进行分割(结果不包含关键字)

strip()将字符串的首尾空格去掉.

如果给了参数,就去掉首尾的参数,但参数必须是位于字符串的首尾

不然去不掉.分支函数lstrip(),rstrip()为去掉左边或者右边的末端空格或字符.

11、字符串的格式化 str.format()

1>"a{0}cd{1}".format("one","two")。

被替换字符用{}包围,用数字格式表示时0,1依次表示format内给定参数的索引位置。

如要想在替换后的字符串中出现花括号,则需在原字符串中进行复写或三写({{0}},{{{1}}})。

对于3.1以上的python,{}内可以为空,不写索引值,系统会默认次数下去为空的{}索引值为

0,1,2,3...

这种替换方法还可用来解决字符串与数字连接会产生TypeError异常的问题。

2>"a{who} was {0}".format(12,who="she") 字段名替代索引方法如左,

但如果同时存在字段名和索引时,索引位置须放置在索引之前.

如样例中不能将0改成1而把对应的参数12放在第二位。

3>对于一个集合(如:stock=["a","b","c"])可用:"{0[1]}{0[2]}".format(stock)

对于一个字典 (如d=dic(a1="xx",a2="xxx")

可用:"{0[a1]}{0[a2]}".format(d) 或者:"{a1}{a2}".format(**d)

在此处为映射拆分操作符,对于已经赋值的变量也可结合内置的locals()函数以相似的方法达成替换,

c="xx";d=34;"{c}ad{d}".format(**locals())。

4>格式转换(r,s,a)用法:{0!r}

s-强制使用字符串格式,r-强制使用表象形式,a-强制使用表象形式(只限于ASCII字符)

5>字符串格式规约(样:"{0:*>10.25}"):以冒号开始,接着为充填字符(*)

然后为对齐字符(>右对齐,<左对齐,^居中对齐),10为最小宽度,25为最大宽度,最大宽度前用"."引导。

所有参数都是可选的,但如果指定了充填符就必须同时指定一个对齐符.(对齐符可单独出现,结果以空格充填)

>整数格式规约

(样:"{0:0^+#15X):与字符的大致相同,+为可选,位于对齐与最小宽度之间(表示必须输出正负号,还有-表示只用输出负号,空格表示正数输出空格负数输出负号),

#位于最小宽度之前,用于输入当前数据类型,

#也可以用0替换(表示用0进行充填,此充填法可不指定对齐方式);

X表示输出数据转换类型:

b二进制,o八进制,x小写十六进制,X大写十六进制,d十进制,c输出整数对应的Unicode字符.

n表示场所敏感输出方式:

   import locale
       locale.setlocale(locale.LC_ALL,"C") #C为场所,也可用en_US.UTF-8替换
       c="{0:n}".format(55)
         )。

整数规约没有最大宽度.

>小数格式规约:

与整数一样,但可以在最小宽度后加个以"."引导的整数来限定小数的位数。

数据类型转换处可用: e,E指数形式,f标准浮点形式,g通常格式,%百分数形式。

tips:输出平方的上标 N\{SUPERSCRIPT TWO},右箭头:\N{RIGHTWARDS ARROW}

基础类:

12、字符串操作函数

s.strip(chars)见上;
s.find(x,start,end)见上;
s.index(x.start,end)见上;
s.format()见上;
s.partition(x)见上;
s.replace(x,y,n)    用y替换x,可选n表示最多替换n次;
s.split(x,n)       最多分割n次,s.rsplit()从右边开始分割;
s.splitlines(f)     返回在行终结符处进行分割产生的列表,并剥离行终结符(除非f为True);
s.count(x,start,end)  计数;
s.join(seq)       返回seq的每个项都以s连接起来的结果,s可以为空;
s.capitalize()       将字符串首字母大写;
s.lower()         将s中的字符变为小写;
s.upper()         返回大写化版本;
s.title()        将每个单词的首字母大写;
s.swapcase()      将大写变小写,小写变大写;
s.islower()       如果s至少有一个可小写的字符且所有可小写的字符都是小写则返回True;
s.isupper()       如果s至少有一个可大写的字符且所有可大写的字符都是大写则返回True;
s.istitle()       如果s是一个非空的首字母大写字符串,则返回True;
s.zfill(w)       返回s的副本,如果比w短,从开始处用0补充,使长度和w一样;
s.center(width,char)  返回一个以s为中心长度为width的字符串,如果有空余则用可选参数char或空格进行填充,如width<len(s),则返回整个s;
s.ljust(width,char)  同上,左对齐;
s.rjust(width,char)  同上,右对齐;
s.encode(endoding,err) 返回一个bytes对象,该对象使用默认的编码格式或指定的编码格式来表示该字符串,并根据可选的err参数处理错误;
s.endswith(x,start,end)如果以x结尾则返回True,否则返回False;
s.startswith(x,start,end)如果以x开始则返回True;
s.expandtabbs(size)  返回s的一个副本,其中的制表符使用8个或指定数量的空格替换;
s.isalnum()       判断是否全是字母数字且非空;
s.isalpha()       判断是否全是字母且非空;
s.isdecimal()      判断是否每个字符都是Unicode的基数为10的数字;
s.isdigit()       判断是否每个字符都是ASCII数字;
s.isidentifier()    判断是否不为空
s.isnumeric()      判断是否每个字符都是数值型的Unicode字符且非空;
s.isprintable()    判断是否每个字符都是可打印的且非空;
s.isspace()       判断是否每个字符都是空白字符;
s.maketrans()
s.translate()

Python3组合数据类型(元组、列表、集合、字典)语法:

一、序列类型(字符串,元组(),列表[])

序列类型支持in,len(),分片[],迭代,5种内置序列类型:

bytearray,bytes,list,str,tuple(元组)。

1、元组可以嵌套 (如:x=str[2][1][0][1])

2、元组的命名(collections.namedtuple(),即自定义)

样:sale=collctions.namedtuple("sale","productid customerid date price")

逗号前的为元组类型的名称,逗号后的参数为字符串,用空格分隔,

每个名称都代表该元组数据类型的一项,

数据项如:x=sale(121,"2017-03-22",1,10.99);

调用某一项则可用x.price来实现,此处结果为10.99;

对于格式化替换,可用**namedtuple._asdict()函数实现直接用名称替换索引,

如:"{productid}{price}".format(**x._asdict())。

此方法用于多层元组较好,name即为最外层元组的name.

单个元素的元组需要加上逗号。

3、列表

1>列表也可存储任意类型的数据,且可使用比较操作符(逐项进行比较)和修改列表内容。

2>列表支持元组的所有操作,同时还有以下函数:

       append()  追加
       count(x)  统计x出现的次数
       index(x,start,end)找x,如没有则产生一个ValueError,
       extend()    (等同于+=),
       insert(i,x)  (在索引位置i处插入x),
       pop()    移除最后一项
       pop(i)    (移除i索引位置处的数据项,如没有i值,则默认移除最后一项),
       remove(x)  (移除从左边开始出现的第一个数据为x的项,如没有则返回一个ValueError),
       reverse()    反转,
       sort()     排序。

对序列特定位置进行赋值可以对列表中单个数据进行替换修改 (x[1]=2;x[1:2]=[a,b],

对片进行替换时新数据项的个数不一定要等于原数据项的个数,可以是任意个数,

结果都是新的分片替换已选定的分片,如果新的替换分片为空,

就相当于删除了已选定的原分片)

del x[1:2]也可以起到删除这一分片的效果(不过del其实是解除了这一数据项与变量之间的绑定)。

3>用*对序列进行拆分赋值

样:a,*b,c=[1,2,3,4,5,6] -> a,b,c=(1, [2, 3, 4, 5], 6)

数据项按位置依次经变量赋值,然后将剩余的所有数据都赋给带有*号的变量。

*的作用就是将一个iterable进行拆分.

的另一个作用是复制操作符,其效果相当于乘号,不过对象不限于数字,可以为任何对象。

4>列表内涵(用于创建一些含有大量数据的列表)

[expression for item in iterable](对iterable中每个数据项进行expression操作)
[expression for item in iterable if condition],对限定条件的对象进行操作。

例:leaps=[y for y in range(1900,2000) if (y%4==0 and y%100!=0)or(y%400==0)]

计算闰年。(range同样为前闭后开)

列表内涵的多变量嵌套:

例:cods=[s+z+c for s in "MF" for z in "SMLX" for c in "BGW"

if not(s=="F" and z=="X")]相当于三层叠加的for循环.

二、集合类型(set)({})

set支持 in ,len(),比较,位逻辑操作符;并且也是iterable的。

只有可hash运算的对象才可以添加到集合中。所有内置的固定数据类型

(float,frozenset,int,str,tupul...)都是可hash运算的。

内置的可变数据类型(如:dict,list,set)都不是可hash运算的。

创建一个集合可用set("a","b",3),且创建一个空集合必须用set()。集合创建时可以存在两个相同的项,但没意义,最终形成的集合只会保留一个。

例:s={2,"veil",("a",5),frozenset({8,4,7}),"a"}

集合是没索引位置区分的,也不能分片或按步距分片。

集合中每个数据都是独一无二的,所以集合常被用于删除重复的数据项(x=list(set(x)))。

1、集合常用函数:

       s.add(x)  添加x到集合s中;
       s.clear()  清空;
       s.pop()    移除集合中任意一项,如果为空了则返回产生KeyError异常;
       s.remove(x) 移除x项,如x不存在就产生KeyError异常;
       s.discard(x)  如果x 存在就移除掉该项;
       s.copy()   浅拷贝;  *
       s.different(t)s-t  返回一个新集合,其只包含s但不在集合t中;  *
       s.difference_update(t)s-=t  移除每一个在集合t但不在s中的项;
       s.intersection(t)s&t     返回s和t的交集;  *

2、集合联合操作运算符结果:

s|t,合集;s&t,交集;s-t,减去与t的交集;s^t,合集减去交集。

3、集合内涵(同列表内涵)

{expression for item in iterable}
{expression for item in iterable if condition}

4、固定集合(frozenset())

一旦创建了就不可改变,同static,可用的函数只有那些不改变集合本身内容的函数(上已用*标注)。

三、映射类型(dict)

映射是键-值数据的无序组合。

内置的映射类型有:

dict(),collections.defaultdict();

对于3.1以上的还有collections.OrderedDict(),它同dict()一样,不过有索引序列。

映射的键只有可hash运算的类型才可使用,而值则可使用任意类型的数据。

1、字典的创建

d=dict(id=1948,name="washer",size=3) #关键字参数
d={"id":1948,"name":"washer","size":3} #面值
d=dict({"id":1948,"name":"washer","size":3}) #面值
d=dict([("id",1948),("name","washer"),("size",3)]) #序列
d=dict(zip(("id","name","size"),(1948,"washer",3))) #序列
{}或用d=dict()来创建一个空字典

2、使用d["id"]则返回相应的值,如果此键不存在,则产生一个KeyError.

d["xx"]=34可添加一个项,如果此键已经存在,则会修改原始的值。
del d["xx"]会删除键为"xx"的项,如果不存在则产生一个KeyError。

3、常用函数(全)

d.clear()  清空
d.copy()  浅拷贝
d.pop(k,v) 返回k的值,并删除k项,如果k不存在,就返回KeyError或者v(如v存在的话)
d.popitem() 移除任意一对键-值,如果d为空就产生KeyError
d.values()  返回字典中所有值的视图
d.keys()   返回字典所有键的视图
d.items()  返回字典所有(key,value)对的视图
d.get(k)   返回k的值,如果k不存在就返回None
d.get(k,v)  返回k的值,如果k不存在就返回v
d.setdefault(k,v) 同get(),如果k不存在就插入一个k项,值为None或者v(如果给了v)
d.fromkeys(s,v) 返回一个dict,它的键为序列s的项,值为None或者v(如果给了v)
d.update(a) 用a更新d,如果键已存在则更新值,如不存在则插入。a可以是dict也可以是(key,value)对的一个iterable.

for

4、对字典的迭代

对键:for key in d: print(key)
或:for key in d.keys(): print(key)
对值:for value in d.values(): print(value)
对键-值:for key,value in d.items(): print(key,value)
或:for item in d.items(): print(item[0],item[1])

5、字典键的视图与项的视图支持一些类似于集合的操作(集合处的联合操作运算)

此可用in来查看某个键是否存在于dict, 也可用联合操作运算查看特定集合的键是否存在于dict,如下:

d={}.fromkeys("ABCD",3);  s=set("ACX"); matches=d.keys()&s  #matches=={'A','C'}

6、字典内涵

{keyexpression:valueexpression for key ,value in terable}
{keyexpression:valueexpression for key ,value in terable if condition}

例:一个字典的键-值反转:inverted_d={v:k for k, v in d.items()}

7、默认字典(collectons.defaultdict())

默认字典永远不会产生KeyError,当查询的键不存在时,字典就会自动生成一个新的以此查询键为键的项,其值为创建字典时设定的默认值。

例:words=collections.defaultdict(int),新增入此字典的默认值就会是数字0。

传入的int为工厂函数(也就是一个不带括号、没有参数的函数),以后可用lambda函数进行简单设置。

8、有序字典(collctions.OrderedDict())

字典的数据项以插入的顺序进行保存,如果用了一个无序的字典来进行update(),得到的结果也会变成无序的。

do=collections.OderedDict([('z',5),(3,6),(8,'a')] )或者先建一个空的,再一项一项的添加。

将一个普通字典转换成有序字典: d=collections.OderedDict(sorted(d.items()))。

四、组合数据的迭代与复制

1、常见迭代操作符与函数:

       s+t  两个序列的连接;
       s*n  返回n个s序列的连接的序列;
       x in s  判断是否在内,not in;
       all(i)    如果iterable i中的每一项都评估为True,则返回True;
       any(i)  如果任意一项为True,则返回True;

enumerate(i,start)通常用于for...in循环,

提供一个(index,item)元组序列,其中的索引起始值为0或start;{相当于将一个序列i折分成单个,

并给每个一个序列号,用(index,item),index为自动产生的序列号,item则依次为i每一项的值}:

 len()返回长度;
max(i,key) 返回iterable i 中最大的项,如果给定的是key函数,就返回key(item)值最大的项;
min(i,key)  同上;
range(start,stop,step) 返回一个数字迭代子,左闭右开,如果没给start,则从0开始;
reversed(i) 反转序列;
sorted(i,key,reverse)   排序;reverse=True时进行逆序排列。

当key存在时可以设置为需要的任意函数规则,甚至可以是自己构造的函数,

如key=abs以绝对值排列,key=str.lower,以str中的lower()函数规则排序。

sorted排序只适用于所有数据项都可以进行互相比较的组合类型,

如果有不同的类型则会产生一个TypeError。

sum(i,start) 求和,start为可选

zip(i1,...,iN)返回元组的迭代子 ,使用迭代子i1到iN;i1-iN都是iterable数据组,例可参考dict的zip构造方式。

只要有某个iterable中的元素用完,就终止迭代过程。

2、用a=iter(iterable结构) 可以获取一个迭代子,在每次循环时可用next(a)方法获取下一个数据项,当结尾时会产生一个StopIteration异常。

3、组合数据类型的复制。

样: b="sudent",a=b 这样的用等号只是简单的将b的值赋给了a

但b的值"student"在系统内并没有被复制成2份,只是a和b都指向"student"这个值,

无论是从a还是从b改变这个对象"student",另一个变量也会显示出改变后的结果。

要想复制出一个"student"的副本则可以用加上类型名:a=str(b);

或者分片的方式a=b[:], 因为提取分片时会产生一个副本。

对于字典和集合类型则用copy()函数来实现。

以上的方法都属于浅拷贝,因为它只会复制对象的第一层内容。

如果对象中还存在可变的iterable对象,它拷贝的只是iterable对象的引用地址,
如果iterable从原对象改变了,拷贝对象的iterable部分也会跟着改变。
如嵌套的列表:['a',['b','c']],复制此对象['b','c']部分时只是复制的一个引用地址。
如果要对此对象进行完全的复制则需用到深拷贝.
import copy; a=copy.deepcopy(b)

4、位置常量命名一般方法:

WATER,TREE,MONEY=range(1,4);那么这三个字符的值依次就为1,2,3

Python3控制结构与函数

1、if语句的另一种写法

expression1 if boolean_expression else expression2
boolean_expression为true时使用expression1,否则用expression2。

常用于默认值的设定。

2、循环结构

while和for循环末尾都可以再加一句else语句。

只要循环正常终止.

else语句就会得到执行,但若由于break或返回语句,以及产生异常导致跳出循环,else语句则不会执行。

3、异常处理完全模块

 try:    suite1
except exception_group1 as varialble1:   suite2  
   #as为可选,
如果有,variable中则存储了该异常。
    except exception_group2 as variabble2
    else:    suite3
    finally:    suite4

如果try的suite1正常执行完毕则会执行else的内容。

如果发生异常则不执行。

finally的suite4无论前边发生什么都会被执行。

即使发生发生的异常在except中找不到相匹配的项,也会执行了finally 再终止程序。

4、异常体系常用分支

Exception:

  ArithmeticError
  EnvironmentError:
    IOError
    OSError
  EOFError
  LookupError:
    IndexError
    KeyError
  ValueError

Exception属于BaseException的子类,BaseException属于object的子类。

异常处理中会由上到下的读取except,如果异常与之匹配,则停止继续向下检索。

所以为了使异常反应得更具体,一般将最小的子类放在最前边。

产生异常:

 raise exception(args)
                 raise exception(args) from original_exception
                   >自定义异常:
       class exceptionName(baseExceiption): pass
       当在语句中想要在某处产生这个异常时就用raise exceptionName()

多个异常也可放在一起(用isinstance()函数进行区分):

except (InvalidEntityError,InvalidTagContentError) ar err:
       if isinstance(err,InvalidNumericEntityError):
              err="invalid numeric entity"
       elif isinstance(err,InvalidAlphaEntityError):
              err="invalid alphabetic entity"

5、自定义函数

格式:

def functionName(arguments):
  suite

包括: 全局函数、局部函数、lambda函数(λ)、方法。

调用一个函数时必须给定全部参数值(如果函数需要参数的话且未指定默认值),不然会产生一个TypeError异常。

调用函数时的参数传递不一定严格按照函数定义时的参数顺序,也可以用name=value的方式进行个别参数的指定传递。

也可以用*做为一个函数的参数,用于表示*位置之后不应该再出现位置参数,否则会产生一个TyepeError。

样:def a(a,*,b=1):pass a(1,2)是错误的调用法,因为它只接受一个位置参数。

也可被称为映射拆分操作符,其作用类似于*对拆分序列类型数据。

6、全局范围的变量(global)

当一个函数用到一个变量,此变量却不在函数内部,那么此变量就是全局变量,在调用这个函数时使用这个变量就必须用global进行声明(global xx),不然此变量就会一直是原始的值,而不是你想要的值。

对于存在于函数之内的函数欲使用上一层函数的变量则使用nonlocal来声明。否则同全局变量一样只能使用不能改变。

7、lambda函数

格式: lambda parameter:expression

parameter是可选的,如果提供,通常以逗号分隔。

expression不能包含分支或循环语句,可以包含条件表达式,也不能包含return。

因函数本身相当于一个有返回计算表达式结果的匿名函数。

如果expression是一个元组,就需要用“()”括起来。

例:area=lambda b,h:05*b*h ;调用方法:area(1,2)

常用于sort表达式中的key: (例:elements.sort(key=lambda e:(e[1],e[2]));忽略第一项);

以及默认字典的默认值设置: (例:rstr=collections.defaultdict(lambda:"No message available") )

8、断言assert:

格式: assert boolean_expression,optional_exprssion

如果boolean_expression结果为False,就产生一个AssertionError,如果给了可选的optional_exprssion,就表达出来。

在最后运行整下程序不想执行assert语句时就用指令-O .

(例:python -O promgramname.py)来实现)

Python3中文件处理:

1、txt,xls,doc等文件的使用

f=open(“filename”,”w”)   
打开一个用于写入的文件,要写入内容时使用f.write(“内容”)        f=open(“filename”,”r”)        
打开一个用于读的文件,读时使用f.read(),返回读取的到的字符串;        f=open(“filename”,”a”)    
打开的文件既可用于读,也可用于写;

注:以上方式打开的文件读取出来的内容是字符串,写入的时候也必须全都是字符串;

2、pickle模块

pickle提供了从python程序中保存数据最简单的方法,原理是直接将数据以二进制进行保存,可以将数据原封不动的保存和读取;但如果加载不可信源有安全危险;

以gzip压缩的文件都以一个特定的魔数引导

f=open(filename,"wb")  
#读取用"rb",追加用"ab",还有"rb+","wb+","ab+"表示可读可写;
pickle.dump(data,fh,pickle.HIGHEST_PROTOCOL)
#pickle文件的写入方法
读取可用pickle.load(fh)

3、文件对象属性与方法

f.close()      关闭文件对象f,并将属性f.close设置为True;
f.close        文件已关闭,则返回True;
f.encoding     byte与str之间进行转换时使用的编码;
f.fileno()     返回底层文件的文件描述符;
f.flush()      清空文件对象;
f.isatty()     如果文件对象与控制台关联,就返回True;
f.mode         文件对象打开时使用的模式;
f.name         文件对象f的文件名(如果有);
f.newlines     文本文件f中的换行字符串的类型;
f.__next__()   返回文件对象f的下一行;
f.peek(n)      返回n个字节,而不移动文件指针的位置;
f.readable()   如果f已经打开等待读取,则返回True;
f.read(count)  文件对象f中读取至多count个字节,如果没有指定count,就读取从当前文件指针直到最后的每个字节,以二进制模式时,返回bytes对象;以文件模式时,返回str对象;
f.readinto(ba) 将至多len(ba)个字节读入到bytearray ba中,并返回读入字节数,如果在文件结尾,就为0;
f.readline(count)      读取下一行,包括\n;
f.readlines(sizehint)     读入到文件结尾之前的所有行,并以列表形式返回;
f.seek(offset,whence)     如果没有给定whence,或其为os.SEEK_SET,就按给定的offset移动文件指针...
f.seekable()    如果f支持随机存取,就返回True;
f.tell()      返回当前指针位置;
f.truncate(size)截取文件到当前文件指针所在位置,如果给定size,就到size大小处;
f.writable()    如果f是为写操作而打开的,就返回True;
f.write(s)      将文本对象s写入到文件;
f.writelines(seq)将对象序列写入到文件;

Python3中的模块:

模块使用哪种语言实现并不重要,因为所有的模块导入与使用的方式都相同。

1、常用模块导入格式:

1 import importable1,importable2,...
2 import importable as preferred_name  
 #将导入的模块自定义名称。如果模块是一个包或包中的一个模块,则需将每一部分用"."进行分隔。
3 from importable import *   
#将包内的所有内容都导入
4 from importable import object1,object2,...
5 from importable import object as preferred_name

from格式有可能导致名称冲突,用from引入大量对象可以使用多行完成或对每个新行进行转义处理。

例: 用from os.path import dirname,就可以直接调用dirname函数.

而不需要每次都从path.dirname()进行调用,

但一旦dirname这个变量被自定义的名字使用,那么dirname就是你自定义的内容,而不是那个调用的函数了,这就是所说的名称冲突.

2、包

包就是一个目录,其中包含一组模块和一个_init_.py文件。

from package import * 将引入包中的所有模块,

因为包中的_init_.py中含有一个包含所有模块名的_all_特殊变量,如果模块名没有在_all_中,就不能被*格式引入。

同样用此*格式也可一起引入一个模块中的所有函数。

3、自定义模块主要结构:

第一行是shebang行,接着是一些注释,接着通常是三引号包含的字符串,

其中提供了模块内容的概览,通常也包括一些使用实例,这也是该模块的docstring;

然后是函数的主体。

一般模块结尾都有这三行:

  if _name_="_main_":
              import doctest
              doctest.testmod()

Python3 面向对象程序设计(类):

一、自定义类

1、属性与方法

格式:

class classname:
    def __init__(self,a,b):
      self.a=a
      self.b=b
    def ...

>一般都有一个__init__函数来定义属于这个类的参数,前后都被"__"包围的函数为特殊方法

;以"__"开头的变量只能读,不能写,相当于private数据。

>如果重新实现str,repr等方法,值应使用表象形式:

def __str__(self):
return "({0.a!r},{0.b!r})".format(self)

>如果调用一个类的方法,python就会自动在类树中进行回溯,如果一直找不到就会产生一个AttributeError.

>在方法前加super()表示调用基类的方法,总是调用super().__init__()是一个种合理的做法。

>自定义类的所有实例都支持==,这种比较总是返回False,通过对特殊方法__eq__()进行重新实现,__ne__()也会跟着自动实现。

>如果我们希望避免不适当的比较,可以使用断言:

(如:assert isinstance(other,Point));也可以用产生TypeError异常来声明不支持这两个对象的比较操作(如:if not isinstance(other,Point):raise TypeError());

方法三 :if not isinstance(other,Point):return NotImplem-emted,但只有在类只对比较特殊方法进行了重新实现才可能返回NotImplemented。

>isinstance()为内置的函数,以一个对象与一个类(或类构成的元组)为参数,如果对象属于给定的类,或基类,就返回True。

>object提供的比较的特殊方法 :__lt__(),__le__(),__eq__(),__ne__(),__ge__(),__gt__()。

2、继承与多态

class classname2(classname):
  def __init__(self)
  ...

classname2是classname的继承类。

多态:给定类的任意对象在使用时都可以看作该类的任意某个基类的对象。

3、使用特性进行属性的存取控制

修饰器(decorator): 是一个函数,该函数以一个函数或方法为参数,并返回参数“修饰后”版本。使用修饰器以@符号引导来进行标记。

例(用内置的property()函数对a的属性进行修饰,使a必须为大于0的数):

@property
def a(self):
    return self.__a
@a.setter
def a(self,a):
    assert a>0,"a must be nonzero and non-negative"
    self.__a=a

每个创建的特性都包含getter,setter,deleter等属性。

4、创建完全整合的数据类型

对于不想要的来自于基类的方法,可以用raise Error的来取消这些方法的使用。

对于要同时取消多个类的情况,可以借助内置的exec()函数来实现,它会动态地执行从给定对象传递来的代码。

二、自定义组合类

组合类型的特殊方法:

__contains__(self,x)     x in y
__delitem__(self,k)      del y[k]
__getitem__(self,k)      y[k]
__iter__(self)          for x in y :pass 返回序列中y中的项或映射y中键的迭代子
__len__(self)          len(y)
__reversed__(self)      reversed(y)
__setitem__(self,k,v)    y[k]=v

对于赋值=后边的值也可以用or,如果第一个值为False,则使用or后边的值(a= b or 3)。

提高篇

python3的正则表达式(regex):

正则表达式提供了一种紧凑的表示法,可用于表示字符串的组合,一个单独的正则表达式可以表示无限数量的字符串。

常用的5种用途: 分析、搜索、搜索与替代、字符串的分割、验证。


(一)正则表达式语言

python中特殊字符有 \.^$?+*{}[]()|

1、字符类速记

^   如果在字符类中第一个字符则表示否定;
-   表示一个字符范围,如果作为字符类中的第一个字符,就表示一个字面意义上的连字符;
.    可以匹配除换行符之外的任意字符,或带re.DOTALL标记的任意字符,或匹配字符类内部的字面意义的字符;
\d  匹配一个Unicode数字,或带re.ASCII标记的[0-9];
\D  匹配一个Unicode非数字,或带re.ASCII标记的[^0-9];
\s   匹配Unicode空白,或带re.ASCII标记的[\t\n\r\f\v];
\S   匹配Unicode非空白,或带re.ASCII标记的[^\t\n\r\f\v];
\w   匹配一个Unicode单词字符,或带re.ASCII标记的[a-zA-Z0-9_];
\W   匹配一个Unicode非单词字符,或带re.ASCII标记的[^a-zA-Z0-9_]

2、量词

格式{m,n},m与n分别表示使用该量词的表达必须匹配的最少次数与最多次数。

如果只给定一个数字则同时表示最小值最大值

量词速记形式:

e{m}   准确匹配表达式e的m次出现
e{m,}   贪婪地匹配表达式e至少m次出现
e{m,}?  非贪婪地匹配表达式e至少m次出现
e{,n}   最多n次出现
e{,n}?   贪婪
e?     e{0,1}
e??    e{0,1}?
e+    e{1,}
e+?    e{1,}?
e*     e{0,}
e*?    e{0,}?
[]     匹配[]内的任意一个内容

()    将()的内容作为一个整体来进行匹配

贪婪表示会尽可以多的匹配符合条件的字符,非贪婪则为尽可以少的匹配。

3、可用air(craft|plane)来匹配 aircraft和airplane。

使用air(?:craft|plane)可以用来限制当处于更多的嵌套中时,aricraft和airplane只有一次捕获。

圆括号表示组。

4、\i反向引用,i表示前面的捕获号。

捕获号也可以用在左圆括号前加 ?P<name>来用名称代替

如:(?P<key>\w+)=(?P<value>.+)对于捕获进行反向引用(?P=name):
(?P<word>\w+)\s+(?P=word) 可以使用名为"word"的捕获来匹配重复的单词。

5、正则表达式断言:

^ 在起始处匹配,也可以在带MULTILINE标记的每个换行符后匹配;
$ 在结尾处匹配,也可以在带MULTILINE标记的每个换行符前匹配;
\A 在起始处匹配;
\b 在单词边界匹配,受re.ASCII影响,如果在字符内部则是backspace的转义字符;
\B 在非单词边界匹配,受re.ASCII影响;
\Z 在结尾处匹配;
(?=e) 如果表达式e在此断言处匹配,但没有超出此处——称为前瞻或正前瞻,则匹配;
(?!e) 如果表达式e在此断言处不匹配,但没有超出此处——称为负前瞻,则匹配;
(?<=e) 如果表达式e恰在本断言之前匹配——称为正回顾,则匹配;
(?<!e) 如果表达式e恰在本断言之前不匹配——称为负回顾,则匹配;

6、正则表达式的注释

可用(?#the comment)来实现,也可用re.VERBOSE标记。

(二)正则表达式模块

正则表达式模块标记:

re.A 或 re.ASCII
re.I 或 re.IGNORECASE 忽略大小写
re.M 或 re.MULTILINE 使^在起始处并在每个换行符后匹配,使$在结尾处但在每个换行符之前匹配
re.S 或 re.DOTALL 使.匹配每个字符,包括换行符
re.X 或 re.VERBOSE 使空白与注释包含在匹配中


正则表达式模块的函数(供查):

re.compile(r,f) 返回编译后的正则表达式r,如果指定,就将其标记设置为f(即上边的re.A等,且可同时有多个标记,用|分隔);(使用re'regex'的形式表达字符串可不用转义)
re.escape(s) 返回字符串s,其中所有非字母数字的字符都使用反斜线进行了转义处理,因此,返回的字符串中没有特殊的正则表达式字符;
re.findall(r,s,f) 返回正则表达式r在字符串s中所有非交叠的匹配(如果给定f,就受其制约)。如果正则表达式中有捕获,那么每次匹配都作为一个捕获元组返回;
re.finditer(r,s,f) 对正则表达式r在字符串s中每个非交叠的匹配(如果给定了f,就受其制约),都返回一个匹配对象;
re.match(r,s,f) 如果正则表达式r在字符串s的起始处匹配(如果给定f,就受其制约),就返回一个匹配对象(MatchObject),否则返回None;
re.search(r,s,f) 如果正则表达式r在字符串s的任意位置匹配(如果给定f,就受其制约),就返回一个匹配对象,否则返回None;
re.split(r,s,m) 返回分割字符串s(在正则表达式r每次出现处进行分割)所产生的字符串的列表,至多分割m次(如果没有给定m,就尽可能多的分割),如果正则表达式中包含捕获,就被包含在分割的部分之间;
re.sub(r,x,s,m) 对正则表达式r的每次匹配(如果给定m,那么至多m次),返回字符串s的一个副本,并将其替换为x--这可以是一个字符串,也可以是一个函数;
re.subn(r,x,s,m) 与re.sub()函数相同,区别在于此函数返回一个二元组;


匹配对象属性与方法:

m.end(g)    返回组g(如果给定)在文本匹配的终点索引位置,对组0,则表示整体匹配;如果匹配中不包含该组,就返回-1;
m.endpos    搜索的终点索引位置
m.expands(s) 返回字符串s,并将其中捕获标识用相应的捕获替代;
m.group(g,...) 返回编号的或命名的组g,如果给定的不止一个,就返回相应的捕获组成的元组;
m.groupdict(difault) 返回一个字典,其中存放所有命名的捕获组,组名作为键,捕获作为值;如果给定了default参数,就将其用作那些不参与匹配的捕获组的值;
m.groups(default) 返回包含所有捕获的元组,从1开始;如果给定default,就将其用作那此不参与匹配的捕获组的值;
m.lastgroup 匹配的、编号最高的捕获组的名称,如果不存在或没有使用名称,就返回None;
m.lastindex   匹配的、编号最高的捕获组的编号,如果没有就返回None;
m.pos    搜索的起始索引位置;
m.re    产生这一匹配对象的正则表达式对象;
m.span(g)   如果给定g,就返回组g在文本中匹配的起始索引位置与结尾位置;(对组0,则是整体匹配);如果该组不参与匹配,就返回(-1,-1);
m.start(g)    如果给定g,就返回组g在文本中匹配的起始索引位置(对组0,则是整体匹配);如果该组不参加匹配,就返回-1;
m.string    传递给match()或search()的字符串;

Python3 多线程编程(thread、threading模块):

threading是对thread的封装。

1、开启线程:

t=threading.Thread(target=sayhi,args=('hh',)) t.start()

或者先建一个Thread的继承类,然后用这个类中的start()方法打开;

2、主进程下开启子进程:

t=multiprocessing.Process(target=work) t.start()

程序会先执行主程序的语句,再执行此子进程的目标函数work();

3、t.setDadmon() 设置守护进程

必须在start()之前设置;如果为True则主程序不用等此线程结束后再结束主程序;

t.join()                 等待线程结束;
t.isAlive()              返回线程是否活动;
t.getName()               返回线程名。
t.setName()               设置线程名。
threading.currentThread()    返回当前线程变量;
threading.enumerate()        返回一个包含正在运行线程的列表;
threading.activeCount()      返回正在运行的线程数量;
threading.Semaphore(5)       限制最大连接数为5,semaphore是一个acquire,release的计数器;

多线程用于IO密集型,如socket,爬虫,web

多进程用于计算密集型,如金融分析;

4、同步锁

R=threading.Lock()
R.acquire()
对公共数据的操作
R.release()

用于对共享资源同步访问的限制,只有当一个线程访问完毕后另一个线程才能访问。

5、死锁

使用RLock()代替Lock()可解决,因为RLock()使资源可以被多次acquire,但只有直到一个线程所有的acquire都被release之后其他线程才能获得资源。

而使用Semaphore(n)则可限制资源的同时最大可访问线程数;

6、Event对象

用于多线程之间的通信和同步,初始情况下event对象中信号标志为False;

Event对象方法:

1 isSet()          返回event的状态值;
2 wait()           如果event.isSet() == False 将阻塞线程,即等待;
3 set()          设置event的状态值;
4 clear()          恢复event的状态值为False; 

7、线程queue

实例queue.Queue() 先进先出;

实例queue.LifoQueue() 后进先出;

实例queue.PriorityQueeu() 接受一个优先级参数,根据优先级大小决定顺序;

优化python程序的几点建议:

1、在需要只读序列时,最好使用元组而非列表;

2、使用生成器yield,而不是创建大的元组和列表并在其上进行迭代处理;

3、尽量使用python内置的数据结构,而不实现自己的自定义结构;

4、从小字符串中产生大字符串时,不要对小字符串进行连接,而是在列表中累积,最后将字符串列表结合成一个单独的字符串;

5、如果某个对象需要多次使用属性访问,或从某个数据结构中进行访问,那么较好的做法是创建并使用一个局部变量来访问对象。

6、可使用字典对多个类似的elif分支进行简化;

functions=dict(a=add,b=edit,l=list)
functions[recieve]() 其中add(),edit(),list()为函数名,recieve为接收的参数;

7、打开读写文件用上下文管理器with语句:

下面是对python复杂语法的一点补充:

1、动态程序设计与内省函数:

__import__()            根据模块名导入模块;
delattr(obj,name)       从对象obj中删除名为name的属性;
getattr(obj,name,val)    返回对象obj中名为name的属性值,如果没有这一属性,并且给定了val参数,就返回val;
setattr(obj,name,val)    将对象obj中名为name的属性值设置为val,必要时候创建该属性;
hasattr(obj,name)       如果对象obj中有名为name的属性,就返回True;
locals()              返回当前本地上下文的字典;
globals()             返回当前全局上下文的字典;
type(obj)             返回对象obj的类型对象;
vars(obj)             以字典形式返回对象obj的上下文,如果没有给定obj,就返回本地上下文;

2、修饰器

修饰器是一个函数,接受一个函数或方法作为其唯一的参数,并返回一个新函数或方法。

一个简单的修饰器函数:

def positieResult(function):
    def wrapper(*args,**kwargs):
        result=function(*args,**kwargs)
        assert result>=0,function.__name__+"()result isn't>=0"
        return result
    wrapper.__name__=function.__name__
    wrapper.__doc__=function.__doc__
    return wrapper

也可用functools模块的wraps函数来取代最后对函数的同步语句:

@functools.wraps(function)
def wrapper(*args,**kwargs):
...

也可在此函数的外国再包一层函数来给修饰器增加可传递参数。

3、def a() ->bool:

suite

表示对函数使用时加注释(3.5后加的新功能)

4、函子另一种包含了特殊方法__call()__的类。

它提供的一个关键好处就是可以维护一些状态信息。

闭包:

def make_strip_function(characters):
    def strip_function(string):
        return string.strip(characters)
    return strip_function

使用方法:

strip_a=make_strip_function(',:;.!?')
strip_a('ladys!')  #returns:'ladys'

相当于二次传参,下面的函子具有相同的功能和用法:

class Strip:
    def __init__(self,characters):
        self.characters=characters
    def __call__(self,string)
        return string.strip(self.characters)

Python3数据库模块(sqlite3,SQLite3):

一、sqlite命令:

创建数据库 :在控制台sqlite3 name

.databases                 查看数据库
.tables                      查看表格名
databaseName .dump > dumpName     将数据库存在文本文件dumpName中,恢复就用databaseName < dumpName;
attach database 'one' as 'other'   将两个数据库绑定在一起;
detach database 'name'             分离数据库;
.schema tableName                  查看表格详情;
create table name;                 创建表;
drop table name;                   删除表;

二、python3中的sqlite3模块:

sqlite3.connect(database [,timeout ,other optional arguments])  打开数据库;如果指数据库存在则返回一个连接对象,如果不存在则会创建一个数据库;
connection.cursor()                             创建一个cursor;
cursor.execute(sql)                                执行一个sql语句,该语句可以被参数化;
connection.execute(sql)                           该例程是上面执行的由光标(cursor)对象提供的方法的快捷方式,它通过调用光标(cursor)方法创建了一个中间的光标对象,然后通过给定的参数调用光标的 execute 方法。
cursor.executemany(sql,seq_of_parameters)                对 seq_of_parameters 中的所有参数或映射执行一个 SQL 命令connection.executemany(sql,seq_of_parameters)     快捷方式;
cursor.executescript(sql_script)                        该例程一旦接收到脚本,会执行多个 SQL 语句。它首先执行 COMMIT 语句,然后执行作为参数传入的 SQL 脚本。所有的 SQL 语句应该用分号(;)分隔
connection.executescript(sql_script)                  快捷方式;
connection.total_changes()                              返回自数据库连接打开以来被修改、插入或删除的数据库总行数;
connection.commit()                                      交当前的事务。如果您未调用该方法,那么自您上一次调用 commit() 以来所做的任何动作对其他数据库连接来说是不可见的。
connection.rollback()                                 回滚自上一次调用commit()以来对数据库所做的更改;
connection.close()                                    关闭数据库连接。请注意,这不会自动调用 commit()。如果您之前未调用 commit() 方法,就直接关闭数据库连接,您所做的所有更改将全部丢失!
conncction.fetchmany([size=cursor.arraysize[)            该方法获取查询结果集中的下一行组,返回一个列表。当没有更多的可用的行时,则返回一个空的列表。该方法尝试获取由 size 参数指定的尽可能多的行。
cursor.fetchall()                                    该例程获取查询结果集中所有(剩余)的行,返回一个列表。当没有可用的行时,则返回一个空的列表。

补充: 连接MySql数据库需用MySQLdb模块来连接;Access数据库用DAO或ADO模块进行连接

Python3常用网络编程模块介绍:

一、网络基础

网络由下往上分为: 物理层、数据链路层、网络怪、传输层、会话层、表示层和应用层。

TCP/IP协议是传输层协议,主要解决数据如何在网络中传输;

socket则是对TCP/IP协议的封装,它本身不是协议,而是一个调用接口;

HTTP、FTP是应用协议,主要解决如何包装数据;

TCP连接的三次握手:

第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

利用Socket建立网络连接的步骤(一对套接字连接过程):

1、服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
2、客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。
为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
3、连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。

而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

TCP和UDP的区别:

TCP是面向连接的,连接经过了三次握手,很大程度的保证了连接的可靠性;
UDP传送数据前并不与对方建立连接,对收到的数据也不发送触诊信号,因此UDP的开销更小,数据传输速率更高。QQ是就采用的UPD协议传输,而相似的MSN采用的是TCP协议传输。

二、socket模块

网络服务都是建立在socket基础之上的,socket是网络连接端点,是网络的基础;

每个socket都被绑定到指定的IP和端口上;

1、首先使用socket(family=AF_INET,type=SOCK_STREAM,proto)函数创建一个对象;

family 地址参数,还可以有AF_INET6,AF_UNIX;

type socket类型;

proto 协议类型,可选参数

创建成功后用bind('127.0.0.1',1051)绑定ip地址和端口,如果地址为空则表示本机;

2、socket对象方法:

bind('127.0.0.1',1051)    绑定ip地址和端口,如果地址为空则表示本机;
    listen(backlog)          监听所有socket对象创建的连接,backlog指定连接队列数,最小为1,最大一般为5;
    connect(address)
    connect_ex(address)      两个都可以连接到服务端,不同的是第一个返回一个错误,第二个返回一个异常;
    accept()              接收来自客户端的数据,返回一个新的socket对象和客户端地址;
    recv(bufsize,flags)      仅返回所接收的字符串;bufsize指定接收缓冲区的大小,flags为可选参数,表示接收标志;
    recvfrom(bufsize,flags)    返回所接收的字符串和地址;
    send(string,flags)       向已经连接的socket发送数据;
    sendall(string,flags)      与send不同的是将会一直发送完全部数据;
    sendto(string,flags,address)可以向一个未连接的socket发送数据;
    makefile(mode,bufsize)     将socket关联到文件对象上,两个参数都是可选的,mode文件模式,bufsize缓冲区大小;
    close()                 完成通信后,应使用close方法关闭网络连接;


# 服务器端实例
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind('127.0.0.1',20178)
sock.listen(5)
conn,address = sock.accept()
print('connect by ',address)
while True:
    data = conn.recv(100)
    if not data:break
    print(data)
    conn.send("anydata")
sock.close()


# 服务器端实例
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind('127.0.0.1',20178)
sock.listen(5)
conn,address = sock.accept()
print('connect by ',address)
while True:
    data = conn.recv(100)
    if not data:break
    print(data)
    conn.send("anydata")
sock.close()

可用select模块来实现多个并发的交互:

# 服务端实例
import socket
import select
import queue
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setblocking(False)   #设置为非阻塞服务
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind('127.0.0.1',20178)
sock.listen(10)
rlists = [sock]
wlists = []
msg_que = {}
timeout = 20
while rlists:
    rs,ws,es = select.select(rlists,wlists,rlists,timeout)
    if not (rs or ws or es):
        print('timeout...')
        break
    for s in rs:
        if s is sock:
            conn,address = s.accept()
            conn.setblocking(False)
            rlists.append(conn)
            msg_que[conn] = queue.Queue()
        else:
            data = s.recv(1024)
            if data:
                print(data)
                msg_que[s].put(data)
                if s not in wlists:
                    wlists.append(s)
            else:
                if s in wlists:
                    wlists.remove(s)
                rlists.remove(s)
                s.close()
                del msg_que[s]
    for s in ws:
            msg = msg_que[s].get_nowait()
        except queue.Empty:
            wlists.remove(s)
    for s in es:
        print('except ',s.getpeername())
        if s in rlists:
            rlists.remove(s)
        if s in wlists:
            wlists.remove(s)
        s.close()
        del msg_que[s]

三、httplib模块

(一)httplib模块内提供了HTTPConnection对象和HTTPRresponse对象;

当创建一个HTTPConnection对象时可用方法有:

1、request(method,url,body,headers) 向服务器发送请求;

method 方法,有"GET","POST"等待连接

body 发送的数据

headers 发送的HTTP头

2、getresponse() 返回一个HTTPResponse对象;

3、close() 关闭与服务器的连接;

4、send(data) 发送数据;

5、putrequest(request,selector,skip_host,skip_accep_encoding) 向服务器发送请求;

request 所发送的操作;

selector 进行操作的URL;

skip_host 若为True则禁止自动发送"POST";

skip_accep_encoding 若为True则禁止自动发送"Accept-Encoding:headers"

6、putheader(headers,argument,...)

headers 发送的HTTP头;

argument 发送的参数;

7、endheaders()

(二)HTTPResponse 对象方法:

1、read() 获得服务器的响应主体;

2、getheader(name,default) 获取服务器响应的HTTP头;

3、version() 查看HTTP协议的版本;

4、status() 查看HTTP协议的状态;

5、reason()

四、ftp模块

1、FTP(host,user,passwd,acct) 创建一个FTP连接对象,此对象的方法有:

FTP(host,user,passwd,acct)    创建一个FTP连接对象
    getwelcome()             获得FTP服务器的欢迎信息
    abort()                   中断文件传输
    sendcmd(command)          发送命令,command为一个字符串
    voidcmd(command)          发送命令,但没有返回值
    retrbinary(command,callback,maxblocksize,rest) 下载文件(二进制)
        command            由"RETR 文件名  组成"
        callback          回调函数
        maxblocksize      每次传输最大字节数
        rest              文件续传位置
    retrlines(command,callback)下载文件(ASCII)
    storbinary(command,file,blocksize)    以二进制上传文件;
    storlines(command,file)    以ASCII形式上传文件;
    dir()                   获取当前目录的内容列表;
    rename(fromname,toname)    重命名
    delete(filename)        删除文件
    cwd(pathname)            改变当前目录
    mkd(pathname)            创建目录
    rmd(dirname)            删除服务器上的目录
    size(filename)           获取文件大小
    set_pasv(boolean)        设置传输模式
    quit()                
    close()                  关闭服务器的连接
set_debuglevel(level)         设置调试级别
connect(host,port)            配置host
login(user,passwd,acct)       登录    

应用操作篇:

tkinter模块常用参数(python3)

1、使用 tkinter.Tk() 生成主窗口(root= tkinter.Tk()

root.title('标题名')      修改框体的名字,也可在创建时使用className参数来命名;
root.resizable(0,0)      框体大小可调性,分别表示x,y方向的可变性;
root.geometry('250x150')  指定主框体大小;
root.quit()         退出;
root.update_idletasks()
root.update()      刷新页面;

2、初级样例

import tkinter
root=tkinter.Tk() #生成root主窗口
label=tkinter.Label(root,text='Hello,GUI') #生成标签
label.pack()        #将标签添加到主窗口
button1=tkinter.Button(root,text='Button1') #生成button1
button1.pack(side=tkinter.LEFT)         #将button1添加到root主窗口
button2=tkinter.Button(root,text='Button2')
button2.pack(side=tkinter.RIGHT)
root.mainloop()             #进入消息循环(必需组件)

3、tkinter中的15种核心组件

Button          按钮;
    Canvas          绘图形组件,可以在其中绘制图形;
    Checkbutton      复选框;
    Entry           文本框(单行);
    Text             文本框(多行);
    Frame           框架,将几个组件组成一组
    Label           标签,可以显示文字或图片;
    Listbox         列表框;
    Menu            菜单;
    Menubutton       它的功能完全可以使用Menu替代;
    Message          与Label组件类似,但是可以根据自身大小将文本换行;
    Radiobutton      单选框;
    Scale           滑块;允许通过滑块来设置一数字值
    Scrollbar        滚动条;配合使用canvas, entry, listbox, and text窗口部件的标准滚动条;
    Toplevel         用来创建子窗口窗口组件。
(在Tkinter中窗口部件类没有分级;所有的窗口部件类在树中都是兄弟。)

4、组件的放置和排版(pack,grid,place)

pack组件设置位置属性参数:
    after:        将组件置于其他组件之后;
    before:       将组件置于其他组件之前;
    anchor:        组件的对齐方式,顶对齐'n',底对齐's',左'w',右'e'
    side:        组件在主窗口的位置,可以为'top','bottom','left','right'(使用时tkinter.TOP,tkinter.E);
    fill            填充方式 (Y,垂直,X,水平)
    expand          1可扩展,0不可扩展
grid组件使用行列的方法放置组件的位置,参数有:
    column:         组件所在的列起始位置;
    columnspam:     组件的列宽;
    row:         组件所在的行起始位置;
    rowspam:      组件的行宽;
place组件可以直接使用坐标来放置组件,参数有:
    anchor:       组件对齐方式;
    x:            组件左上角的x坐标;
    y:             组件右上角的y坐标;
    relx:          组件相对于窗口的x坐标,应为0-1之间的小数;
    rely:           组件相对于窗口的y坐标,应为0-1之间的小数;
    width:          组件的宽度;
    heitht:        组件的高度;
    relwidth:       组件相对于窗口的宽度,0-1;
    relheight:     组件相对于窗口的高度,0-1;

5、使用tkinter.Button时控制按钮的参数:

anchor:            指定按钮上文本的位置;
    background(bg)       指定按钮的背景色;
    bitmap:            指定按钮上显示的位图;
    borderwidth(bd)    指定按钮边框的宽度;
    command:          指定按钮消息的回调函数;
    cursor:            指定鼠标移动到按钮上的指针样式;
    font:               指定按钮上文本的字体;
    foreground(fg)     指定按钮的前景色;
    height:            指定按钮的高度;
    image:             指定按钮上显示的图片;
    state:              指定按钮的状态(disabled);
    text:               指定按钮上显示的文本;
    width:             指定按钮的宽度
    padx               设置文本与按钮边框x的距离,还有pady;
    activeforeground    按下时前景色
    textvariable        可变文本,与StringVar等配合着用

6、文本框tkinter.Entry,tkinter.Text控制参数:

background(bg)      文本框背景色;
    foreground(fg)        前景色;
    selectbackground    选定文本背景色;
    selectforeground    选定文本前景色;
    borderwidth(bd)      文本框边框宽度;
    font                 字体;
    show                文本框显示的字符,若为*,表示文本框为密码框;
    state               状态;
    width              文本框宽度
    textvariable        可变文本,与StringVar等配合着用

7、标签tkinter.Label组件控制参数:

Anchor            标签中文本的位置;
    background(bg)    背景色;
    foreground(fg)      前景色;
    borderwidth(bd)     边框宽度;
    width             标签宽度;
    height            标签高度;
    bitmap             标签中的位图;
    font               字体;
    image             标签中的图片;
    justify            多行文本的对齐方式;
    text             标签中的文本,可以使用'\n'表示换行
    textvariable       显示文本自动更新,与StringVar等配合着用

8、单选框和复选框Radiobutton,Checkbutton控制参数:

anchor           文本位置;
    background(bg)   背景色;
    foreground(fg)    前景色;
    borderwidth       边框宽度;
    width            组件的宽度;
    height           组件高度;
    bitmap           组件中的位图;
    image            组件中的图片;
    font             字体;
    justify          组件中多行文本的对齐方式;
    text             指定组件的文本;
    value            指定组件被选中中关联变量的值;
    variable          指定组件所关联的变量;
    indicatoron        特殊控制参数,当为0时,组件会被绘制成按钮形式;
    textvariable       可变文本显示,与StringVar等配合着用

9、组图组件Canvas控制参数:

background(bg)      背景色;
    foreground(fg)       前景色;
    borderwidth       组件边框宽度;
    width             组件宽度;
    height             高度;
    bitmap             位图;
    image             图片;
绘图的方法主要以下几种:
    create_arc          圆弧;
    create_bitmap      绘制位图,支持XBM;
    create_image       绘制图片,支持GIF(x,y,image,anchor);
    create_line         绘制支线;
    create_oval;        绘制椭圆;
    create_polygon     绘制多边形(坐标依次罗列,不用加括号,还有参数,fill,outline);
    create_rectangle   绘制矩形((a,b,c,d),值为左上角和右下角的坐标);
    create_text         绘制文字(字体参数font,);
    create_window      绘制窗口;
    delete              删除绘制的图形;
    itemconfig          修改图形属性,第一个参数为图形的ID,后边为想修改的参数;
    move               移动图像(1,4,0),1为图像对象,4为横移4像素,0为纵移像素,然后用root.update()刷新即可看到图像的移动,为了使多次移动变得可视,最好加上time.sleep()函数;
    只要用create_方法画了一个图形,就会自动返回一个ID,创建一个图形时将它赋值给一个变量,需要ID时就可以使用这个变量名。
    coords(ID)          返回对象的位置的两个坐标(4个数字元组);
对于按钮组件、菜单组件等可以在创建组件时通过command参数指定其事件处理函数。方法为bind;或者用bind_class方法进行类绑定,bind_all方法将所有组件事件绑定到事件响应函数上。

10、菜单Menu

参数: 
    tearoff          分窗,0为在原窗,1为点击分为两个窗口
    bg,fg           背景,前景
    borderwidth      边框宽度
    font              字体
    activebackgound   点击时背景,同样有activeforeground,activeborderwidth,disabledforeground
    cursor
    postcommand
    selectcolor      选中时背景
    takefocus
    title       
    relief
    menu.add_cascade      添加子选项
    menu.add_command      添加命令(label参数为显示内容)
    menu.add_separator    添加分隔线
    menu.add_checkbutton  添加确认按钮
    delete                删除

11、事件关联

bind(sequence,func,add)——
bind_class(className,sequence,func,add)
bind_all(sequence,func,add)
事件参数:  
sequence              所绑定的事件;
func                   所绑定的事件处理函数;
add                    可选参数,为空字符或‘+’;
className             所绑定的类;
鼠标键盘事件
    <Button-1>            鼠标左键按下,2表示中键,3表示右键;
    <ButtonPress-1>        同上;
    <ButtonRelease-1>    鼠标左键释放;
    <B1-Motion>           按住鼠标左键移动;
    <Double-Button-1>     双击左键;
    <Enter>               鼠标指针进入某一组件区域;
    <Leave>               鼠标指针离开某一组件区域;
    <MouseWheel>         滚动滚轮;
    <KeyPress-A>         按下A键,A可用其他键替代;
    <Alt-KeyPress-A>      同时按下alt和A;alt可用ctrl和shift替代;
    <Double-KeyPress-A>    快速按两下A;
    <Lock-KeyPress-A>     大写状态下按A;
    Activate             当组件由不可用转为可用时触发;
    Configure            当组件大小改变时触发;
    Deactivate          当组件由可用转变为不可用时触发;
    Destroy              当组件被销毁时触发;
    Expose              当组件从被遮挡状态中暴露出来时触发;
    Unmap              当组件由显示状态变为隐藏状态时触发;
    Map                  当组件由隐藏状态变为显示状态时触发;
    FocusIn              当组件获得焦点时触发;
    FocusOut            当组件失去焦点时触发;
    Property             当窗体的属性被删除或改变时触发;
    Visibility           当组件变为可视状态时触发;
event对象(def function(event)):
    char                按键字符,仅对键盘事件有效;
    keycode            按键名,仅对键盘事件有效;
    keysym             按键编码,仅对键盘事件有效;
    num                鼠标按键,仅对鼠标事件有效;
    type                 所触发的事件类型;
    widget               引起事件的组件;
    width,heigh        组件改变后的大小,仅Configure有效;
    x,y                鼠标当前位置,相对于窗口;
    x_root,y_root       鼠标当前位置,相对于整个屏幕

12、弹窗

messagebox._show函数的控制参数:
    default         指定消息框按钮;
    icon            指定消息框图标;
    message        指定消息框所显示的消息;
    parent          指定消息框的父组件;
    title           标题;
    type            类型;
simpledialog模块参数:
    title           指定对话框的标题;
    prompt         显示的文字;
    initialvalue    指定输入框的初始值;
  filedialog    模块参数:
    filetype       指定文件类型;
    initialdir     指定默认目录;
    initialfile    指定默认文件;
    title         指定对话框标题
colorchooser模块参数:
    initialcolor    指定初始化颜色;
    title           指定对话框标题;

13、字体(font)

一般格式:

('Times -10 bold')

('Times',10,'bold','italic') 依次表示字体、字号、加粗、倾斜


补充:

config 重新配置
label.config(font='Arial -%d bold' % scale.get())
依次为字体,大小(大小可为字号大小),加粗
tkinter.StringVar 能自动刷新的字符串变量,可用set和get方法进行传值和取值,类似的还有IntVar,DoubleVar...

sys.stdout.flush()  刷新输出

附1:tkinter中的颜色

附2:一个自己用tkinter写的计算器程序:

#filename:Caculater
import tkinter,time,decimal,math,string
root=tkinter.Tk()
root.title('计算器')
root.resizable(0,0)
global cuncu, vartext, result, fuhao
result = fuhao = None
vartext = tkinter.StringVar()
cuncu = []
class anjianzhi:
    global cuncu, vartext, result, fuhao
    def __init__(self,anjian):
        self.anjian = anjian
    def jia(self):
        cuncu.append(self.anjian)
        vartext.set( ''.join(cuncu))
    def tui(self):
        cuncu.pop()
        vartext.set(''.join(cuncu))
    def clear(self):
        cuncu.clear()
        vartext.set('')
        result = None
        fuhao = None
    def zhengfu(self):
        if cuncu[0]:
            if cuncu[0] == '-':
                cuncu[0] = '+'
            elif cuncu[0] == '+':
                cuncu[0] = '-'
            else:
                cuncu.insert(0, '-')
        vartext.set(''.join(cuncu))
    def xiaoshudian(self):
        if cuncu.count('.') >= 1:
        else:
            if cuncu == [] :
                cuncu.append('0')
            cuncu.append('.')
            vartext.set(''.join(cuncu))
    def yunshuan(self):
        global cuncu, vartext, result, fuhao
        if vartext.get() == '':
        else:
            get1 = decimal.Decimal(vartext.get())
            if self.anjian in ('1/x','sqrt'):
                if self.anjian == '1/x':
                    result = 1/get1
                elif self.anjian == 'sqrt':
                    result = math.sqrt(get1)
            elif  self.anjian in ('+','-','*','/','='):
                if fuhao is not None:
                    get1 = decimal.Decimal(result)
                    get2 = decimal.Decimal(vartext.get())
                    if fuhao == '+':
                        result = get1 + get2
                    elif fuhao == '-':
                        result = get1 - get2
                    elif fuhao == '*':
                        result = get1 * get2
                    elif fuhao == '/':
                        result = get1 / get2
                else:
                    result = get1
                if self.anjian == '=':
                    fuhao = None
                else:
                    fuhao = self.anjian
            print(fuhao)
            print(result)
            vartext.set(str(result))
            cuncu.clear()
def copy1():
    # tkinter.Misc().clipboard_clear()
    tkinter.Misc().clipboard_append(string(vartext.get()))

用python语言编写网络爬虫:

本文主要用到python3自带的urllib模块编写轻量级的简单爬虫。

至于怎么定位一个网页中具体元素的url可自行百度火狐浏览器的firebug插件或者谷歌浏览器的自带方法。

1、访问一个网址

re=urllib.request.urlopen('网址‘)

打开的也可以是个urllib.request.Request对象,后边也可以跟数据参数,当有传入数据时会自动变为POST请求;

2、urllib.request.Request(url,data=None,headers={})对象属性和方法

full_url
    selector
    method    
    get_method()
    add_header(key,val)
    add_unredirected_header(key,header)
    has_header(header)
    remove_header(header)
    get_full_url(header)
    set_proxy(host,type)
    get_header(header_name,default=None)
   header_items()

3、已连接对象的可用方法:

1 re.read()             读取内容,想要将内容保存下来,需先新建一个相应格式的文件,再将读取到的内容写入到这个文件内即可;
2 re.geturl()            可取得已打开对象的url地址;
3 re.info()             可取得响应服务器的信息;
4 re.getcode()           可取得响应状态码;
5 urllib.parse.urlencode()  将一个存储post数据的字典转换成打开网页所需要的数据格式;

可用json.loads()将文本转换成键值对;

可在传地址时将header以一个字典数据的形式传入,以隐藏自己的访问方式

也可用re.add_header('') 的方式进行追加;

4、当知道一个文件的url时可用此方法直接下载保存到本地

urllib.request.urlretrieve(' wx1.sinaimg.cn/mw600/9b ','bc.jpg')

5、登录功能的实现(post)

(1)利用session保留登录状态:

login_data = {
            '_xsrf': getXSRF(baseurl),
            'password': password,
            'remember_me': 'true',
            'email': email,
session = requests.session()
content = session.post(url, headers = headers_base, data = login_data)
s = session.get("http://www.zhihu.com", verify = False)
print s.text.encode('utf-8')

(2)利用cookie进行登录:

post = {
            'ua':self.ua,
            'TPL_checkcode':'',
            'CtrlVersion': '1,0,0,7',
            'TPL_password':'',
#将POST的数据进行编码转换
postData = urllib.urlencode(post)
cookie = cookielib.LWPCookieJar()
cookieHandler = urllib2.HTTPCookieProcessor(cookie)
opener = urllib2.build_opener(cookieHandler, urllib2.HTTPHandler)
#第一次登录获取验证码尝试,构建request
request = urllib2.Request(loginURL,postData,loginHeaders)
#得到第一次登录尝试的相应