简介

Python 是一个高层次的结合了解释性、交互性和面向对象的脚本语言。解释型语言: 这意味着开发过程中没有了编译这个环节。作为解释型语言,意味着开发过程中没有了编译这个环节,对代码逐行解析。

Python还具有可嵌入性,如Python无法运行的代码可以使用C或C++完成程序,然后从的Python程序中调用。也提供了数据库接口和GUI编程。

Python作为解释性语言,内核时Python解析器,任何安装了解析器的系统都可以运行Python文件。

基础语法

标识符
Python默认utf-8编码,所有字符串都是 unicode 字符串。标识符的第一个字符必须是字母表中字母或下划线’_’。标识符的其他的部分有字母、数字和下划线组成。标识符对大小写敏感。

Python保留字

>>> import keyword>>> keyword.kwlist['False', 'None', 'True', '__peg_parser__', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']


Python注释

#这是单行注释"""这是多行注释这是多行注释"""'''也可以用三个单引号来进行多行注释'''

缩进
Python 使用缩进来表示代码块。缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。

基本数据类型

Python 中有六个标准的数据类型:

  • Number(数字)
  • String(字符串)
  • List(列表)
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)

Python3 的六个标准数据类型中:

不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

可变数据和不可变数据的“变”是相对于引用地址来说的,不是不能改变其数据,而是改变数据的时候会不会改变变量的引用地址。

数字:运算符+,-,* ,/ ,%与其它语言一样括号 ()用于分组,/会保留小数部分,取而代之的是//** 运算符计算幂乘方 ,更高级计算需要引入数学计算库。

字符:Python 也提供单引号'...'或双引号"..." 标识字符。\ 可以用来转义,也可以使用 原始字符串,方法是在第一个引号前面加上一个r会原样输出。

切片

# 要取得一段子串的话,可以用到​变量[头下标:尾下标]​,就可以截取相应的字符串str="qwertyuiop"print(str[0:5])#qwert

类型判断
python可以用type函数来检查一个变量的类型:

type(name))

列表
列表List可以完成大多数集合类的数据结构实现。它支持字符,数字,字符串甚至可以包含列表(也就是嵌套)。

列表用​[ ]​标识。是 Python 最通用的复合数据类型。

list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]tinylist = [123, 'john'] print list # 输出完整列表print list[0] # 输出列表的第一个元素print list[1:3] # 输出第二个至第三个的元素 print list[2:] # 输出从第三个开始至列表末尾的所有元素print tinylist * 2 # 输出列表两次print list + tinylist # 打印组合的列表

元组
元组Tuple是另一个数据类型,类似于 List(列表)。

元组用”()”标识。内部元素用逗号隔开。但是元素不能二次赋值,相当于只读列表。

tuple = ( 'abcd', 786 , 2.23, 'john', 70.2 )tinytuple = (123, 'john') print tuple # 输出完整元组print tuple[0] # 输出元组的第一个元素print tuple[1:3] # 输出第二个至第三个的元素 print tuple[2:] # 输出从第三个开始至列表末尾的所有元素print tinytuple * 2 # 输出元组两次print tuple + tinytuple # 打印组合的元组

字典
字典 (dictionary) 是除列表以外 Python 之中最灵活的内置数据结构类型。列表是有序的对象集合,字典是无序的对象集合。

两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。

字典用”{ }”标识。字典由索引 (key) 和它对应的值 value 组成。

dict = {}dict['one'] = "This is one"dict[2] = "This is two"tinydict = {'name': 'john','code':6734, 'dept': 'sales'}print dict['one'] # 输出键为'one' 的值print dict[2] # 输出键为 2 的值print tinydict # 输出完整的字典print tinydict.keys() # 输出所有键print tinydict.values() # 输出所有值

数据类型转换

对数据内置的类型进行转换,只需要将数据类型作为函数名即可。

输入输出流
input()函数作为输出流,print()函数作为输入流

name=input()print(name)

变量
变量是存储在内存中的值。就是指针无关数据类型,解释器会分配指定大小的内存。

# 等号(=)用来给变量赋值counter = 100 # 赋值整型变量miles = 1000.0 # 浮点型name = "John" # 字符串# 多个对象指定多个变量a, b, c = 1, 2, "john" 

文本换行
使用+ \起到多行连接的作用:

data="this" + \"is" + \"Tuesday"print(data)#thisisTuesday# 空格也会被视为字符

内置库和函数

数学计算库
Python ​math ​模块提供了许多对浮点数的数学运算函数。
Python ​cmath ​模块包含了一些用于复数运算的函数。

import math


字符串运行算回切片获取

内置函数

关键字

自定义函数

Python函数的定义。定义函数需要用def 关键字实现,具体的语法格式如下:

def 函数名(参数列表)://实现特定功能的多行代码[return [返回值]]
def func(a,b):return a+bfunc(1,2)# 3

Python 支持在函数内部定义函数,此类函数又称为局部函数。

#全局函数def outdef ():#局部函数def indef():print("http://c.biancheng.net/python/")#调用局部函数indef()#调用全局函数outdef()

局部变量一样,默认情况下局部函数只能在其所在函数的作用域内使用。

lambda 表达式
对于定义一个简单的函数,Python 还提供了另外一种方法,lambda 表达式,又称匿名函数,常用来表示内部仅包含 1 行表达式的函数。如果一个函数的函数体仅有 1 行表达式,则该函数就可以用 lambda 表达式来代替。

name = lambda [list] : 表达式def name(list):return 表达式name(list)

eval() 和 exec() 函数
eval() 和 exec() 函数的功能是相似的,都可以执行一个字符串形式的 Python 代码(代码以字符串的形式提供),相当于一个 Python 的解释器。二者不同之处在于,eval() 执行完要返回结果,而 exec() 执行完不返回结果。

面向对象

Python 是一门面向对象的编程语言。类和对象是 Python 的重要特征,相比其它面向对象语言,Python 很容易就可以创建出一个类和对象。同时,Python 也支持面向对象的三大特征:封装、继承和多态。

面向对象中,常用术语包括:

  • 类:可以理解是一个模板,通过它可以创建出无数个具体实例。比如,前面编写的 tortoise 表示的只是乌龟这个物种,通过它可以创建出无数个实例来代表各种不同特征的乌龟(这一过程又称为类的实例化)。
  • 对象:类并不能直接使用,通过类创建出的实例(又称对象)才能使用。这有点像汽车图纸和汽车的关系,图纸本身(类)并不能为人们使用,通过图纸创建出的一辆辆车(对象)才能使用。
  • 属性:类中的所有变量称为属性。例如,tortoise 这个类中,bodyColor、footNum、weight、hasShell 都是这个类拥有的属性。
  • 方法:类中的所有函数通常称为方法。不过,和函数所有不同的是,类方法至少要包含一个 self 参数(后续会做详细介绍)。例如,tortoise 类中,crawl()、eat()、sleep()、protect() 都是这个类所拥有的方法,类方法无法单独使用,只能和类的对象一起使用。

在 Python 中,所有的变量其实也都是对象,包括整形(int)、浮点型(float)、字符串(str)、列表(list)、元组(tuple)、字典(dict)和集合(set)。以字典(dict)为例,它包含多个函数供我们使用,例如使用 keys() 获取字典中所有的键,使用 values() 获取字典中所有的值,使用 item() 获取字典中所有的键值对。

Python类的定义
Python 中定义一个类使用 class 关键字实现,其基本语法格式如下:

class 类名:多个(≥0)类属性...多个(≥0)类方法...

构造方法
在创建类时,我们可以手动添加一个__init__() 方法,该方法是一个特殊的类实例方法,称为构造方法(或构造函数)。

def __init__(self,...):代码块

注意,此方法的方法名中,开头和结尾各有 2 个下划线,且中间不能有空格。Python 中很多这种以双下划线开头、双下划线结尾的方法,都具有特殊的意义。

类的构造方法最少也要有一个 self 参数。self 所表示的都是实际调用该方法的对象。无论是类中的构造函数还是普通的类方法,实际调用它们的谁,则第一个参数 self 就代表谁。相当于Java的this。

类的实例化
创建类对象的过程,又称为类的实例化。类名(参数)

定义的类只有进行实例化后,才能得到利用。实例化后的类对象可以执行以下操作:

  • 访问或修改类对象具有的实例变量,甚至可以添加新的实例变量或者删除已有的实例变量;
  • 调用类对象的方法,包括调用现有的方法,以及给类对象动态添加方法。

类变量
在类体中,根据变量定义的位置不同,以及定义的方式不同,类属性又可细分为以下 3 种类型:

  • 类体中、所有函数之外:此范围定义的变量,称为类属性或类变量;
  • 类体中,所有函数内部:以“self.变量名”的方式定义的变量,称为实例属性或实例变量;
  • 类体中,所有函数内部:以“变量名=变量值”的方式定义的变量,称为局部变量。

类变量的特点是,所有类的实例化对象都同时共享类变量
实例变量只作用于调用方法的对象。另外,实例变量只能通过对象名访问,无法通过类名访问。
局部变量只能用于所在函数中,函数执行完成后,局部变量也会被销毁。

类方法
类方法也可以进行更细致的划分,具体可分为类方法、实例方法和静态方法。

采用 @classmethod 修饰的方法为类方法;采用 @staticmethod 修饰的方法为静态方法;不用任何修改的方法为实例方法。

实例方法最大的特点就是,它最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)。实例方法通常会用类对象直接调用。

Python 类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,Python 会自动将类本身绑定给 cls 参数(注意,绑定的不是类对象)。也就是说,我们在调用类方法时,无需显式为 cls 参数传参。和 self 一样,cls 参数的命名也不是规定的(可以随意命名)。

类方法推荐使用类名直接调用,当然也可以使用实例对象来调用(不推荐)。

class CLanguage:#类构造方法,也属于实例方法def __init__(self):self.name = "C语言中文网"self.add = "http://c.biancheng.net"#下面定义了一个类方法@classmethoddef info(cls):print("正在调用类方法",cls)

类的静态方法中无法调用任何类属性和类方法。

class CLanguage:@staticmethoddef info(name,add):print(name,add)

setter和setter
Python 中,通过使用描述符,可以让程序员在引用一个对象属性时自定义要完成的工作。

class revealAccess:def __init__(self, initval = None, name = 'var'):self.val = initvalself.name = namedef __get__(self, obj, objtype):print("Retrieving",self.name)return self.valdef __set__(self, obj, val):print("updating",self.name)self.val = val

属性封装
使用用“类对象.属性”的方式访问类中定义的属性,其实这种做法是欠妥的,因为它破坏了类的封装原则。正常情况下,类包含的属性应该是隐藏的,只允许通过类提供的方法来间接实现对类属性的访问和操作。

在不破坏类封装原则的基础上,为了能够有效操作类中的属性,类中应包含读(或写)类属性的多个 getter(或 setter)方法,这样就可以通过“类对象.方法(参数)”的方式操作属性。此时属性要定义为实例属性。

class CLanguage:#构造函数def __init__(self,name):self.name = name #设置 name 属性值的函数 def setname(self,name):self.name = name#访问nema属性值的函数def getname(self):return self.name#删除name属性值的函数def delname(self):self.name="xxx"

这种操作类属性的方式比较麻烦,更习惯使用“类对象.属性”这种方式。Python 中提供了 property() 函数,可以实现在不破坏类封装原则的前提下,让开发者依旧使用“类对象.属性”的方式操作类中的属性。

class CLanguage:#构造函数def __init__(self,n):self.__name = n#设置 name 属性值的函数def setname(self,n):self.__name = n#访问nema属性值的函数def getname(self):return self.__name#删除name属性值的函数def delname(self):self.__name="xxx"#为name 属性配置 property() 函数name = property(getname, setname, delname, '指明出处')

封装

封装机制保证了类内部数据结构的完整性,因为使用类的用户无法直接看到类中的数据结构,只能使用类允许公开的数据,很好地避免了外部对内部数据的影响,提高了程序的可维护性。


还可以定义以单下划线“_”开头的类属性或者类方法,这种类属性和类方法通常被视为私有属性和私有方法。

继承

继承机制经常用于创建和现有类功能类似的新类,又或是新类只需要在现有类基础上添加一些成员(属性和方法),但又不想直接将现有类代码复制给新类。也就是说,通过使用继承这种机制,可以轻松实现类的重复使用。

子类继承父类时,只需在定义子类时,将父类(可以是多个)放在子类之后的圆括号里即可。语法格式如下:

class 类名(父类1, 父类2, ...)#类定义部分

注意,如果该类没有显式指定继承自哪个类,则默认继承 object 类(object 类是 Python 中所有类的父类,即要么是直接父类,要么是间接父类)。另外,Python 的继承是多继承机制(和 C++ 一样),即一个子类可以同时拥有多个直接父类。

多继承经常需要面临的问题是,多个父类中包含同名的类方法。对于这种情况,Python 的处置措施是:根据子类继承多个父类时这些父类的前后次序决定,即排在前面父类中的类方法会覆盖排在后面父类中的同名类方法。

方法重载
子类继承了父类,那么子类就拥有了父类所有的类属性和类方法。通常情况下,子类会在此基础上,扩展一些新的类属性和类方法。

在子类定义一个同名同类型和参数的方法,重写方法体即可。

使用super() 函数访问父类成员或方法。但如果涉及多继承,该函数只能调用第一个直接父类的构造方法。

super().__init__(self,...)

多态

Python 是弱类型语言,其最明显的特征是在使用变量时,无需为其指定具体的数据类型。

类的特殊成员

__new__() 是一种负责创建类实例的静态方法,它无需使用 staticmethod 装饰器修饰,且该方法会优先 __init__() 初始化方法被调用。

通常情况下,直接输出某个实例化对象,得到的信息只会是“类名+object at+内存地址”,对我们了解该实例化对象帮助不大。通过重写类的__repr__() 方法,当我们输出某个实例化对象时,其调用的就是该对象的 __repr__()方法,输出的是该方法的返回值。

__del__() 方法,功能正好和 __init__() 相反,其用来销毁实例化对象。创建的类实例化对象后续不再使用,在适当位置手动将其销毁,释放其占用的内存空间(整个过程称为垃圾回收(简称GC))。

__dir()__函数,通过此函数可以获取某个对象拥有的所有的属性名和方法名,该函数会返回一个包含有所有属性名和方法名的有序列表。

__dict__ 属性。需要注意的一点是,该属性可以用类名或者类的实例对象来调用,用类名直接调用 __dict__,会输出该由类中所有类属性组成的字典;而使用类的实例对象调用 __dict__,会输出由类中所有实例属性组成的字典。

hasattr()函数用来判断某个类实例对象是否包含指定名称的属性或方法。

hasattr(obj, name)

getattr()函数获取某个类实例对象中指定属性的值。

getattr(obj, name[, default])

setattr() 函数的功能相对比较复杂,它最基础的功能是修改类实例对象中的属性值。其次,它还可以实现为实例对象动态添加属性或者方法。

setattr(obj, name, value)

迭代器
列表(list)、元组(tuple)、字典(dict)、集合(set)这些序列式容器有一个共同的特性,它们都支持使用 for 循环遍历存储的元素,都是可迭代的,因此它们又有一个别称,即迭代器。
实现如下 2 个方法:

  • __next__(self):返回容器的下一个元素。
  • __iter__(self):该方法返回一个迭代器(iterator)。

装饰器
@staticmethod、@classmethod 和 @property,其中 staticmethod()、classmethod() 和 property() 都是 Python 的内置函数。

使用函数装饰器 A() 去装饰另一个函数 B(),其底层执行了如下 2 步操作:将 B 作为参数传给 A() 函数;将 A() 函数执行完成的返回值反馈回 B。

函数装饰器,就是通过装饰器函数,在不修改原函数的前提下,来对函数的功能进行合理的扩充。

异常处理

Python 中,用try except语句块捕获并处理异常,其基本语法结构如下所示:

try:
可能产生异常的代码块
except [ (Error1, Error2, … ) [as e] ]:
处理异常的代码块1
except [ (Error3, Error4, … ) [as e] ]:
处理异常的代码块2
except [Exception]:
处理其它异常

在原本的try except结构的基础上,Python 异常处理机制还提供了一个 else 块,也就是原有 try except 语句的基础上再添加一个 else 块,即try except else结构。使用 else 包裹的代码,只有当 try 块没有捕获到任何异常时,才会得到执行;反之,如果 try 块捕获到异常,即便调用对应的 except 处理完异常,else 块中的代码也不会得到执行。

try:result = 20 / int(input('请输入除数:'))print(result)except ValueError:print('必须输入整数')except ArithmeticError:print('算术错误,除数不能为 0')else:print('没有出现异常')print("继续执行")

Python 异常处理机制还提供了一个 finally 语句,通常用来为 try 块中的程序做扫尾清理工作。在整个异常处理机制中,finally 语句的功能是:无论 try 块是否发生异常,最终都要进入 finally 语句,并执行其中的代码块。

try:a = int(input("请输入 a 的值:"))print(20/a)except:print("发生异常!")else:print("执行 else 块中的代码") finally :print("执行 finally 块中的代码")

注意,和 else 语句不同,finally 只要求和 try 搭配使用,而至于该结构中是否包含 except 以及 else,对于 finally 不是必须的(else 必须和 try except 搭配使用)。

raise在在程序的指定位置手动抛出一个异常。

raise [exceptionName [(reason)]]

其中,用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息。

sys 模块中的 exc_info() 方法获得更多的异常信息。

模块

Python 提供了强大的模块支持,主要体现在,不仅 Python 标准库中包含了大量的模块(称为标准模块),还有大量的第三方模块,开发者自己也可以开发自定义模块。通过这些强大的模块可以极大地提高开发者的开发效率。

使用import导入模块的语法
import 模块名1 [as 别名1], 模块名2 [as 别名2],…:使用这种语法格式的 import 语句,会导入指定模块中的所有成员(包括变量、函数、类等)。不仅如此,当需要使用模块中的成员时,需用该模块名(或别名)作为前缀,否则 Python 解释器会报错。
from 模块名 import 成员名1 [as 别名1],成员名2 [as 别名2],…: 使用这种语法格式的 import 语句,只会导入模块中指定的成员,而不是全部成员。同时,当程序中使用该成员时,无需附加任何前缀,直接使用成员名(或别名)即可。

用 [] 括起来的部分,可以使用,也可以省略。

自定义包与模块
包其实就是文件夹,包含py文件的文件夹。手动创建一个包,只需进行以下 2 步操作:新建一个文件夹,文件夹的名称就是新建包的包名;创建py文件。

导入也很简单,主要有三种方式:

  • import 包名[.模块名 [as 别名]]
  • from 包名 import 模块名 [as 别名]
  • from 包名.模块名 import 成员名 [as 别名]

用 [] 括起来的部分,是可选部分,即可以使用,也可以直接忽略。

模块属性与方法
查看模块成员:dir()函数,通过 dir()函数获取到的模块成员,不仅包含供外部文件使用的成员,还包含很多“特殊”(名称以 2 个下划线开头和结束)的成员,列出这些成员,对我们并没有实际意义。

import stringdir(string)

查看模块成员:__all__变量,除了使用 dir() 函数之外,还可以使用 __all__变量,借助该变量也可以查看模块(包)内包含的所有成员。__all__ 变量在查看指定模块成员时,它不会显示模块中的特殊成员。

__doc__ 属性,查看模块(包)的具体功能。
__file__ 属性查找该模块(或包)文件所在的具体存储位置,直接查看其源代码。

IO处理

Python 提供了内置的文件对象,以及对文件、目录进行操作的内置模块,通过这些技术可以很方便地将数据保存到文件(如文本文件等)中。

在 Windows 上,路径书写使用反斜杠 “” 作为文件夹之间的分隔符,但在 OS X 和 Linux 上,使用正斜杠 “/” 作为它们的路径分隔符。需要两个第一个是转义字符。

对文件的系统级操作功能单一,比较容易实现,可以借助 Python 中的专用模块(os、sys 等),并调用模块中的指定函数来实现。

import osos.remove("a.txt")

文件的应用级操作可以分为以下 3 步,每一步都需要借助对应的函数实现:

  • 打开文件:使用 open() 函数,该函数会返回一个文件对象;
  • 对已打开文件做读/写操作:读取文件内容可使用read()、readline() 以及 readlines()函数;向文件中写入内容,可以使用 write() 函数。
  • 关闭文件:完成对文件的读/写操作之后,最后需要关闭文件,可以使用close()函数。

如果想要操作文件,首先需要创建或者打开指定的文件,并创建一个文件对象,而这些工作可以通过内置的 open()函数实现:

file = open(file_name [, mode='r' [ , buffering=-1 [ , encoding = None ]]])


Python 提供了如下 3 种函数,它们都可以帮我们实现读取文件中数据的操作:

  • read() 函数:逐个字节或者字符读取文件中的内容;
  • readline() 函数:逐行读取文件中的内容;
  • readlines() 函数:一次性读取文件中多行内容。

Python 中的文件对象提供了 write() 函数,可以向文件中写入指定内容。如:file.write(string)
close() 函数是专门用来关闭已打开文件的,如:file.close()

实现对文件指针的移动,文件对象提供了 tell() 函数和 seek() 函数。tell() 函数用于判断文件指针当前所处的位置,而 seek() 函数用于移动文件指针到文件的指定位置。

tell() 函数的用法很简单,如:file.tell()
seek() 函数用于将文件指针移动至指定位置,如:file.seek(offset[, whence])

使用 with as 操作已经打开的文件对象(本身就是上下文管理器),无论期间是否抛出异常,都能保证 with as 语句执行完毕后自动关闭已经打开的文件:

with 表达式 [as target]:代码块