一、基本说明

1.运行环境

Python是解释型语言,可以在解释型的交互器中输入后立即执行。不过在关闭解释器后,所有的数据会消失。

也可以将程序保存成py为后缀的文件,在python的运行环境中执行。为了防止在程序结束之后,立即关闭程序窗口,可以用一个input()函数结尾

2.行和语句结束

在Python中,换行或者符号";"都表示单行的语句结束

如果一条语句需要跨越多行,但又要连续,可以使用字符"\"来连接不同行(在前一行的末尾使用符号"\")

包含在()、[]、{}中的语句不需要使用"\"符号,会自动成为连续的一行

3.代码块

在Python中,不再使用"{}"来分隔代码块,而是通过缩进距离来分隔代码块。缩进距离相同的代码,会被认为是处于同一代码块中的代码。

如果缩进出现错误,可能会出现”IndentationError: unexpected indent“的错误

4.注释单行注释:使用符号#开头,到本行结束为止的内容,都算是单行注释的内容

多行注释:用成对的3个单引号,或者3个双引号包含起来的内容,都算是多行注释的内容

5.标识符(变量名、函数名)

标识符规则:区分大小写

只能由字母、数字、下划线组成,不能用数字开头

命名约定:以1个下划线开头的,代表不能直接访问的类属性,需要通过类提供的接口进行访问,也不能用“from xxx import *"来导入

以2个下划线开头的,代表类的私有成员,在子类中不能访问

以2个下划线开头,2个下划线结尾的,代表python里的特殊方法

6.变量

Python中,变量不需要声明,不用指定变量类型

可以将函数名赋值给变量,然后就能使用变量名来调用函数,方式为:变量名(参数列表)

7.保留关键字:

保留关键字列表:and、exec、not、assert、finally、or、break、for、pass、class、from、print、continue、raise、def、if、return、del、import、try、elif、in、while、else、is、with、except、lambda、yield

global修饰:

写在变量名第1次出现时,变量名的左侧,表示该变量是一个全局变量。

二、基础语法

1.数据类型

Python中支持八进制、十六进制的数据。

none:none是python的一个内建值,代表什么都没有。

整型:

类型:int:取值范围-2147483648~2147483648

long

说明:默认为int

如果整型数据后面带上字母L,表示长整型

如果int数据超过数据范围,会自动被转换为long

浮点型:

复合型:

复合型数据可以表示虚数,一般数据格式是实数与虚数的和。

实数包括整数、浮点数。

布尔型:

布尔型的数据就包含两种值:True、False

2.数据类型转换

转换为布尔型:bool()

3.运算符号

说明:不要比较两种不兼容的数据类型,结果不确定且没有意义

有些比较运算符可以连续使用,例如:0 < age < 10

两个字符串或者序列可以进行大小的比较,比较规则在本地化设置(locale)中

逻辑表达式采用的是短路逻辑的计算方式,一旦能确定结果就立即结束运算返回结果

赋值符号的扩展应用:

赋值符号是=,不过Python中的赋值语句有比较多的扩展应用,在下方说明。

普通赋值: 语法:变量名 = 值

序列解包: 序列解包的原理是,将=左右两侧的数据看成序列,用右边序列中的元素依次给左边序列中的元素赋值。

语法:变量1,变量2,变量3=值1,值2,值3 说明:把多个值按照顺序,依次赋给=左侧的变量

左右序列元素个数必须相同

可以直接让2个变量交换赋值,例如:a,b=b,a

=右侧的值,可以是是列表、元组、字典

=左侧的最后1个变量可以用*修饰,此时会把右侧还未使用的所有值赋给这个变量,同时这个变量会自动变成1个列表。在引用这个变量时不用*修饰。

链式赋值: 语法:a=b=c=1 说明:将一个值同时赋给多个变量

增量赋值: 语法:x+=1

说明:这些符号都可以写成增量赋值的形式:+、-、*、/、%

如果数据类型不支持某种运算符号,赋值的时候不能使用这种运算的增量赋值

三、数据结构

1.字典

字典由多个键值对组成(键值对也称为项),可通过键名来引用键值。这种类型的数据结构称为映射。字典是python中唯一内建的映射类型。

键名的类型可以是:数字、字符串、元组。

字典是可以嵌套的,多层嵌套的字典数据,格式和JSON一致。

嵌套字典中的键引用,需要写出多个键名,类似于引用多维数组的成员,例如:people[China][ZheJiang]

字典中的各个键值对,没有顺序的概念。

字典的格式:用{}包围

每个键值对之间用","分隔开

一个键值对中,键名和键值用":"分隔开

空字典为:{}

字典的常见操作:

字典的方法:

2.序列

序列是按照某一顺序,组合在一起的元素集合。序列中的各个元素,可以不是同一种数据类型。

序列可以作为另一个序列的元素,例如:person1=['Lily',12] person2=['Lucy',12] people=[person1,person2]

Python中,字符串可以理解为序列,序列也可以理解为是字符串。序列的标准操作,对于字符串对象都可以使用。

序列类型:

列表:列表中的数据可以修改。一个列表用[]包含起来,不同元素之间,用","分隔开,例如:person1=['Lily',12]

元组:元组中的数据不能修改,其他特性与列表完全一致。

一个元素用()包含起来,不同元素之间,用","分隔开。即使元组只有1个元素,也必须在元素后面加上","。

当输入一个值,再连上一个","时,会自动创建出一个元组。

元组可以在映射中,当做键来使用,但是列表不行。

元组是很多内建函数和方法的返回形式。

索引:

索引就是序列中每个元素的编号,第1个元素的索引是0。也可以使用负数索引,最后一个元素的负数索引是-1。

序列中的单个元素,通过 '序列名[索引]' 这种方式来访问

字符串的值可以直接使用索引来引用其中的元素,而不需要通过变量引用,例如:'hello'[1]

函数的返回值也可以直接使用索引来引用其中的元素,例如:input("show message")[1]

分片:

分片是指通过指定两个索引,引用这两个索引之间的元素,引用出来的结果仍然是序列。

语法:序列名[索引1:索引2,步长] 说明:第1个索引可以为空,表示从序列的第1个元素开始引用。

第2个索引可以大于序列的长度,也可以为空,这两种方式都表示取到序列的最后一个元素。

步长可以选择是否使用,默认值为1,此时第1个索引,必须小于第2个索引,否则引用结果为空。当步长为负数时,第1个索引必须大于第2个索引,表示从右向左引用。

注意:分片引用的范围是两个序列的左闭右开区间。例如:people=[1,2,3] people[1:2]取出的结果是[2]。

列表的分片赋值:可以使用另一个列表对分片进行赋值,直接修改原列表。

赋值列表中元素的个数,可以不等于分片中元素的个数。

当赋值元素个数大于分片元素个数时,会在原列表中插入多出的元素,同时分片后面的元素向右顺延位置。

当赋值元素个数小于分片元素个数时,分片中多出的元素会被删除掉

注意:当分片的步长不等于1时,赋值元素的个数,必须等于分片元素的个数

序列的常见操作:

序列的方法:

列表的常见操作:

列表的方法:

3.字符串

在Python3.0之后,所有字符都使用Unicode编码。字符串需要用单引号或双引号包含

如果字符串的值带有单引号或者双引号,可以用另外一种引号来包含,也可以使用转义字符\

如果字符串的值跨越多行,需要使用3个引号来包含,也可以在每行末尾用\对换行符进行转义。此时对值内的单、双引号不用 转义

字符串值不能以\结尾

所有标准的序列操作对于字符串都适用,包括:索引、分片、乘法、判断成员资格、求长度、取最小值、取最大值

字符串是不可变的,所有针对字符串、字符串索引、字符串分片的赋值都是非法的。

符号%进行字符串格式化:

字符串格式化,是指将一些指定的值,嵌入到其他字符串中。

两部分字符串用字符串格式化操作符号%连接。%左边放置格式化字符串,%右边放置被格式化的值。例如:print("hello %s"%"world"),打印结果是:“hello world”。

格式化字符串中,需要用转换说明符来标注出需要嵌入字符串的位置、长度等信息。如要格式化字符串中要将%当做普通值,需要使用%%

被格式化的值,可以是单个字符串,此时会替换掉格式化字符串中的一个值。也可以是元组或者字典,元组和字典的值必须是字符串类型,此时可以替换掉格式化字符串中的多个值。

注意:除了元组以外的序列类型,会被当做单个值处理。

转换说明符以%开头,后面可以跟5个参数,语法:

% (键名)转换格式 最小宽度 .精度 转换类型

说明:键名:视情况而定是否需要,如果被格式化的值是一个字典,那么必须使用(键名)来标注需要带入的值

转换格式:可选,包括4个选项:-表示左对齐;+表示整数前面要显示+号,负数前面显示-号;空格表示正数前面要空一格;0表示如果转换类型是数据型的且位数不够时,空位显示0

最小宽度:可选,如果值是正整数,表示转换后的字符所占的最小宽度,单位是字符个数,如果格式化的值小于该宽度,会用空格补上(如果是数据类型并且转换格式为0,会用0补上);也可以设置成符号*,表示具体数值从元组中读取

精度:可选,必须符号.开头,跟上一个正整数,可以设置成符号*,表示具体数值从元组中读取。如果转换类型是数据类型的,精度表示保留的小数点后的位数;如果转换类型是字符串,表示字符串显示的最大宽度。如果格式化的值大于该值,会舍弃右边超出的值。转换类型为字符串时,精度可以小于最小宽度。此时会先根据精度,对格式化的值进行取舍,然后再根据最小宽度补上空格来补位。

转换类型:必选,常见选项包括:d表示带符号整型;f表示十进制浮点型;s表示用str转换的字符串;其他选项待补充

其他格式化方法:

在String模块中,提供了另外一种格式化方法:模板字符串。相当于在格式化字符串中,使用特殊的变量名来代替转换说明符,然后给这些变量赋值,来达到格式化的目的。

生成格式化字符串,需要使用Template方法,例如:s = Template('$x,"啦啦啦",$x'),这里的$x就是变量名,规则如下:如果在格式化字符串中,变量值是一个独立的单词,那格式为"$变量名"

如果在格式化字符串中,变量值是某个单词的一部分,格式为:"${变量名}"

如果在格式化字符串中,需要将$作为普通值,需要使用$$

生成格式化字符串后,需要调用字符串的substitute方法,来带入变量值,例如s.substitue('x=test')

除了'x=test'这个关键字参数外,substitute还可以使用字典作为参数,此时格式化字符串中的变量名,必须是字典中的键名。调用substitute方法时,直接使用字典名作为参数,就能够完成多个键值对的带入。

也可以使用safe_substitute方法来带入变量值,这个方法不会因为缺少值或者$字符使用不对而出错

字符串的方法:

四、功能语句

1.引用模块

模块是已经完成的程序文件,相当于其他语言中使用的库。引用模块后,就可以在本文件中使用其他模块的方法。

引用模块的语句,必须写在程序文件的头部

引用整个模块:

语法:import ModuleName as AliasName

说明:通过这种方式引用模块,会引用该模块中的所有方法

as AliasName表示给引用的模块起一个别名,可以用别名来调用这个模块中的方法,可选。

对应的方法调用语法:语法:ModuleName.FunctionName()

语法:AliasName.FunctionName()

引用部分方法:

语法:from ModuleName import FunctionName1,FunctionName2... as AliasName

说明:用这种方式,只会引用import右侧的方法。

FunctionName可以是多个,多个方法名用,分隔开。

可以用符号*代替方法名列表,表示引用模块中的所有方法。

如果用这种部分引用方式,从不同模块中引用了多个同名方法,只有最早引入的那个方法可用。可以给同名方法取不同别名来解决这个问题。

as AliasName表示给引用的方法起一个别名,可以用别名来调用这个方法,可选。

对应的方法调用语法:语法:FunctionName()

语法:AliasName()

2.条件判断

语法:

if 条件1:

执行语句1

elif 条件2:

执行语句2

else:

执行语句3

3.断言

断言的作用是,判断一个表达式的真假,如果表达式为假,则终止程序运行,并且显示一段提示。

语法:assert 判断语句,解释语句

4.循环

while循环:

语法:while 判断语句:执行语句

for循环:

语法:

for 元素 in 元素集合

执行代码语句块

说明:元素集合必须是一个可迭代的对象

如果要遍历一个数字的范围,可以使用range()函数生成一个数字序列

有两种方式来遍历字典:for key in d 这种方法,只能遍历出字典中的键名,不过可以根据d[key]的方法来取出键名

for key,value in d.items() 这种方法,可以遍历取出字典中的键名和键值

五、自定义函数

1.基本定义语法

语法:

def FunctionName(ParamList):

函数体的语句块

说明:def是定义函数的关键字

2.函数说明文档

可以在函数体的语句块开头部分,直接写入字符串,这部分字符串称为文档字符串,会作为函数的一部分进行储存,例如:

def square(x):

'这是文档字符串,用来解释说明本函数'

函数体的语句块

文档字符串可以用以下的方式进行访问:FunctionName._doc。_d其实是函数的属性,结尾的双下划线表示他是个特殊属性。

Python内建的help()函数,其实就是用来显示函数的文档字符串的,所以以下两条语句的作用是一样的: - help(FunctionName) - FunctionName._doc__

3.返回值

所有的函数都会有返回值。如果用return语句设定了返回值,那么函数会返回指定值。如果没有return语句,或者return语句后面内容为空,那么函数返回一个None。

4.收集参数

多个参数组成元组:

定义函数时可以形参前加上符号*,在调用函数给该参数赋值时,程序会将剩余所有还未进行赋值的位置参数,组成1个元组,赋值给该参数。如果没有剩余的位置参数可用,该参数会被赋予一个空元组。

示例:

def Func(a,b,*c):

pass

Func(1,2,3,4,5)

c实际获得的赋值是:(3,4,5)

注意:参数带上符号之后,参数名还是原来的参数名,引用的时候不要加上符号

多个参数组成字典:

定义函数时可以形参前加上符号**,在调用函数给该参数赋值时,程序会将剩余所有还未进行赋值的位置参数组成1个字典,赋值给该参数。如果没有剩余的位置参数可用,该参数会被赋予一个空字典。字典的键名是关键字参数名,键值是参数值。

示例:

def Func(a,b,**c):

pass

Function(a=1,b=2,d=3,e=4)

c实际得到的赋值是:{'c':3,'e':4}

5.参数的逆收集

在指定实参时可以给一个元组实参前面加上符号*,此时程序会将这个元组拆分后一一赋值给形参。

示例:

def Function(a,b,c)

param=(1,2,3)

Function(*param)

此时,param元组中的元素会被拆分开,一一赋值给形参,最终的赋值结果是:a=1,b=2,c=3

在指定实参的时候,可以给一个字典实参前面加上符号**,此时程序会将这个字典拆分后一一赋值给形参。

6.位置参数

在调用自定义函数时,可以仅指定参数值,这种调用写法叫做位置参数。实参会按照从左到右的顺序,依次赋值给形参。

def Func1(a,b,c)

函数语句块

Func1(1,2,3)

7.关键字参数

在调用自定义函数时,也可以通过键值对的方式指定参数,这种调用写法叫做关键字参数。实参会按照每个值指定的形参进行赋值。

def Func1(a,b,c)

函数语句块

Func1(a=1,b=2,c=3)

使用关键字参数进行赋值时,实参的顺序可以打乱。当参数很多,顺序很难记忆时,关键字参数能够让实参更加清晰便利。

在定义函数的时候,也可以用关键字参数来指定每个参数的默认值,写法如下:def Func1(a=1,b=2,c=3)

当参数具有默认值时,在调用函数的时候,就可以不给该参数提供实参值。

8.作用域

函数内部的名称,包括参数在内,都只作用在函数范围这个局部区域内,不会与函数外部的名称产生冲突。

当函数内的参数被赋予新值时,不会改变外部变量的任何值。

但是如果当函数内外的两个变量,引用同一个列表时,任意一个参数的变化,都会引起列表的变化,从而引起另一个参数的变化。为了避免这种情况,可以取出列表的一个完整切片,赋值给局部变量。因为切片总是返回一份列表的副本,避免两个变量引用同一份列表。

变量产生作用的区域,称为命名空间或者作用域。在Python中,作用域是用字典来表示的。在Python中,除了全局作用域外,每一次函数调用都会创建1个新的作用域。

使用内建的vars()函数,可以查看全局作用域中的变量以及对应的值。使用内奸的locals()函数可以查看局部作用域的变量以及对应的值。

在函数内部,如果不创建与全局变量同名的变量,就可以使用全局变量名,来调用全局变量。

9.函数的嵌套

函数嵌套的作用不是很大,除非希望通过函数,来创建另一个函数。

语法:

def Func1(num1):

def Func2(num2):

return num1*num2

return Func2

当调用函数Func1的时候,Func2被作为返回值,返回给一个变量。此时该变量名就相当于函数名Func2,可以用该变量名来调用函数Func2。

使用上面这中定义函数的方式,有两个特点:Func2能够完全访问Func1的局部变量

只调用Func1的话,Func2是不会被执行的

10.递归

递归是指在一个函数的定义语句块中,调用了该函数自身。

有用的递归啊函数包含2个部分:当函数直接返回值时有基本实例。

递归实例,包括一个或者多个问题较小部分的递归调用。

每次函数被调用时,针对这个调用的新作用域就会被创建,这意味着当函数调用自身时,实际运行的是两个不同的函数。

递归在大多数情况下都可以使用循环来代替,并且循环的效率更高,但是递归算法更容易读懂。

六、类和对象

对象基本上可以看做数据以及由一系列可以存取、操作这些数据的方法所组成的集合。

1.类的特性

多态:

多态意味着就算不知道变量所引用的对象类型是什么,还是能对它进行操作,而它也会根据对象类型的不同而表现出不同的行为。例如符号"+",当左右两边为数值类型时,执行数学的加法操作;当左右两边为字符串时,执行字符串合并的操作。

任何不知道对象到底是什么类型,但是又要对对象“做点儿什么”的时候,都会用到多态。这不仅限于方法,很多内建运算符和函数都有多态的性质。

唯一能够毁掉多态的就是使用函数来显示地检查数据类型,例如type、isinstance、issubclass等函数。如果可能的话,应该尽力避免使用这些毁掉多态的函数。真正重要的是如何让对象按照你所希望的方式工作,不管它是否是正确的类型

封装:

封装是指向程序中的其他部分隐藏对象的具体实现细节。

继承:

定义新类时,可以让新类从一个已有类中获取所有的特性和方法,这种操作称为继承。

例如类A继承了类B,那么类A会自动拥有类B的所有特性和方法,类A成为类B的子类,类B成为类A的基类、超类、父类。

2.类和类型

在旧版本的Python中,类和类型之间有很明显的区别。内建的对象是基于类型的,自定义的对象则是基于类的,可以创建类但是不能创建类型。

在最近的Python中,基本类型和类之间的界限开始模糊了,可以创建内建类型的自类,而这些类型的行为更像是类。

创建类:

创建类的关键字是class,语法如下:

_metaclass__= type

class ClassName(SuperClass):

def Function1(self):

pass

def Function2(self):

pass

说明:_metaclass__= type是为了说明声明的类是新式类,该语句必须放在模块或者脚本开头的地方。

在函数定义的地方,会创建自己的命名空间

self是对对象自身的引用

SuperClass是ClassName这个类的超类,ClassName从SuperClass类中继承所有的特性和方法。

方法:

方法会将对对象自身的引用,作为自己的隐藏参数。这是方法和普通函数的本质区别。

特性:

对象中定义的属性成为特性。

特性应该具有两种属性:公有、私有。公有指的是类之外的代码能够直接访问。私有指的是类之外的代码不能直接访问,只能通过类提供的接口进行访问。

Python中无法直接将特性定义为私有类型的,不过有特殊方法能够实现。在特性名前面,加上双下划线"__"就表示该特性是私有的。此时在类外,通过"__"+特性名的方式无法访问该特性。

在类的内部定义中,以双下划线开头的特性,被翻译成了以类名+""开头的特性,实际上使用 类名+""+特姓名这种方式,能够访问到私有特性。

简而言之,确保其他人不会访问对象的方法和特性是不可能的,但是这类名称的变化,就是提醒他们的强有力信号。

命名空间:

位于class语句块中的代码,都在特殊的命名空间中执行——类命名空间。

类的定义其实就是执行代码块,这一点非常有用。

如果类中的特性,在定义类的时候就进行了赋值,那么该特性相当于一个该类的所有对象都能够访问的公用特性。只要对象中的该特性不进行重新赋值,就能够访问到这个公共值。如果对象中的该特性重新进行赋值,那么就只能访问到重新赋予的值。这种公用特性和对象特性的关系,就好像全局变量和局部变量的关系。

特殊特性:_bases__:基类名

_class__:类名

dict:对象中所有存储的值

多个超类:

在进行继承的时候,可以指定多个超类,从而让子类从多个超类中继承特性和方法,这种行为称为多重继承。除非特别熟悉多重继承,都则应该尽量避免使用这种行为。

如果多个超类中,具有同名的特性或者函数,子类会继承写在较左侧的那个超类。

七、函数库

文件的方法:

八、对象属性库