一、Python介绍
概述
- 特点:本意“蟒蛇”,89年由“河南人”龟叔编写,开源(从规范到解释器)、跨平台,是一种胶水语言。
- 优点:设计哲学是“优雅”、“明确”、“简单”。口号是“人生苦短,我用Python”,IEEE编程语言排行榜第1位。
- 适合开发web网站和网络服务、系统工具和脚本。代码少、开发速度快。
- 缺点:解释性语言,相比于编译型语言C或Java的运行速度慢,且代码不能加密。
- 应用领域:Web开发,大数据,人工智能,自动化运维,云计算,爬虫,游戏开发等。使用python开发的网站:Openstack、豆瓣、Dropbox、Youtube视频分享服务、Facebook大量基础库、Google网络搜索系统、对冲基金和银行等。
- 解释器:官方版本的解释器CPython,此外还有其他各种解释器。
mac本地安装
1、安装:Python有两个版本,一个是2.x版(2000年发布),一个是3.x版(2008年发布),这两个版本是不兼容的。mac之前自带2.7,可使用以下命令查看。喜大普奔,mac的12.3版本已经移除python2。
1 | $ python3 -V |
2、配置
1 | $ pip3 install --upgrade pip #更新pip3 |
3、运行
可使用IDE,PyCharm创建项目时,使用virtualenv做版本管理,输入python3的路径。每个应用可能需要各自拥有一套虚拟的“独立”的Python运行环境。virtualenv就是用来为一个应用创建一套“隔离”的Python运行环境。
1 | $ pip3 install virtualenv |
可以直接在命令行输入python或python3,看到提示符>>>就表示我们已经在Python交互式环境中了,可以输入任何Python代码,回车后会立刻得到执行结果。输入exit()或quit()回车,就可以退出Python交互式环境。
或者在命令行直接运行文件
python hello.py
第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码。
1 | #!/usr/bin/env python3 |
在mac和linux上,可以添加第一行注释后(标识这是一个Python可执行程序),提升权限后直接执行。
1 | chmod a+x hello.py |
IDE
- IDLE
- PyCharm
- Microsoft Visual Studio
- Eclipse + PyDev
- Jupyter Notebook
重点推荐Jupyter Notebook,当学习、测试、写文档分享时,可以使用这个工具,可快速根据ipynb直接导出md、pdf等多种格式的文档,十分方便。相关快捷键可以参考mac常用开发软件专题。
1 | $ pip3 install jupyter #安装 |
linux部署
1 | $ yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel |
二、Python基础
语法特点
- input()和print()是在命令行下面最基本的输入和输出。
- 字符串是以’单引号’或”双引号”括起来的任意文本,合理使用单双引号可以避免使用转义字符。
- 单行注释为#。语法上没有多行注释,可用3单引号或双引号代替。
- Python允许用’’’…’’’的格式表示多行字符串内容(和多行注释一致,注意区别)。
- Python程序是大小写敏感的。
- 每一行都是一个语句,不建议行尾使用分号(当然一定使用分号也行)。当语句以冒号:结尾时,缩进的语句视为代码块。
- 缩进使用4个空格或1个Tab。建议使用空格。涉及党派之争,慎重选择,但底线是不可混用。
- 采用PEP8(Python Enhancement Proposal)作为编码规范,包括使用()将多行内容隐式连接,使用空行增加代码可读性,运算符两侧、函数参数之间、逗号两侧使用空格分割,避免在循环中用+运算符累加字符串等。
- 命名规范,模块名小写用下划线分隔多个字母,类名首字母大写,模块内部的类名采用下划线,函数、类属性和方法同模块名,使用单下划线开头的模块变量或函数是受保护的,使用双下划线开头的实例变量或方法是私有的。
- 保留字,True、False、None这3个以外,其他的都是小写。pass为空语句。
- 变量,必须是有效的标识符(字母、数字和下划线组成,不能是保留字),慎用小写字母l和大写字母O。
- 八进制以0o/0O开头,十六进制以0x/0X开头。
字符集和编码相关
字符集,ASCII 1个字节,GBK 2个字节,Unicode做统一,有2字节的UCS-2和4字节的UCS-4(或UTF-32)之分,但没有规定编码。
在计算机内存中统一使用Unicode字符集,但Unicode没有规定编解码。当需要保存到硬盘或者需要传输的时候,需要进行编解码。
本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8或UTF-16。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。UTF-16编码定长为2字节或4字节。
unicode转换成UTF-8,会形成了如下的UTF-8标记位:
0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
例如,何,unicode为01001111 01010101
对应的UTF-8为:11100100 10111101 1001010101,其中加粗的二进制为填充内容。
在最新的Python 3版本中,字符串是以Unicode编码的。
对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:
1 | print('人生苦短,我用Python') |
条件判断:
1 | if <条件判断1>: |
循环:
1 | 'Michael', 'Bob', 'Tracy'] names = [ |
序列
包含列表、元组、字典、集合和字符串。有索引、切片、相加、相乘、元素是否是序列成员,提供len、max、min、list、sum、str、sorted、reversed、enumerate等内置函数操作。其中,集合和字典不支持索引、切片、相加、相乘操作。
名称 | 英文 | 表示 | 特点 |
---|---|---|---|
列表 | List | [“A”,”B”] | 有序,可重复,可修改,下标从0开始,最后一个下标为-1。 |
元组 | Tuple | (“A”,”B”) | 有序,可重复,不可修改 |
字典 | Dict | {key1:value1,key2:value2} | 无序,key不能重复 |
集合 | Set | set([‘A’, ‘B’, ‘C’])/set{‘A’,’B’,’C’} | 无序,元素不能重复 |
列表:list
1 | index=1 |
元组:tuple
tuple是另一种有序列表,和list非常类似,list使用中括号,tuple使用小括号。但是tuple一旦初始化后元素就不能修改,除非整体替换。元组比列表的访问和处理速度快。
1 | classmates = ('Michael', 'Bob', 'Tracy') |
字典:dictionary
字典通过键而不是索引来读取。是任意对象的无须集合。字典是可变的,但键必须唯一且不可变(元素可以作为键,但列表不可以)。
1 | dic = {'Michael': 95, 'Bob': 75, 'Tracy': 85} |
和list比较,dict有以下几个特点:
查找和插入的速度极快,不会随着key的增加而变慢;
需要占用大量的内存,内存浪费多。
而list相反:
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。
无序和无重复元素的集合:set
1 | s = set([1, 2, 3]) #使用set(iteration)函数创建 |
字符串
1 | str ='人生苦短,我用python!' |
格式化字符串,可使用%操作符,或者format()方法。
1 | # 格式化 |
字符串长度与编码关系,bytes类型带有b前缀的字符串,str类型为Unicode表示。
encode是将字符串(str类型)转换为二进制数据(bytes类型),称为编码。
decode是二进制数据转换为字符串,称为解码。
1 | # 字符串长度与编码关系 |
正则表达式
- 用\d可以匹配一个数字
- \w可以匹配一个字母或数字
- .可以匹配任意字符
- 匹配变长的字符,用*表示任意个字符(包括0个)
- 用+表示至少一个字符
- 用?表示0个或1个字符
- 用{n}表示n个字符
- 用{n,m}表示n-m个字符
- 要做更精确地匹配,可以用[]表示范围
1 | import re |
针对flags,是re的模块修饰符。
修饰符 | 说明 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别匹配 |
re.M | 多行匹配,影响^和dollar符号 |
re.S | 使匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符 |
re.X | 给予更灵活的格式 |
索引
正数索引,第一个元素下标为0。负数索引,最后一个元素下标为-1。
切片
sname[start,end,step]
start为切片开始位置(包含),end为切片截止位置(不包含),step为步长默认为1。
1 | L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] |
迭代
Python的for循环抽象程度要高于C的for循环,因为Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。
1、列表list生成式
1 | for x in range(1, 11)] [x * x |
2、生成器
1 | for x in range(10)] [x * x |
三、高级功能
函数调用
python不允许程序员选择采用传值还是传引用。Python参数传递采用的肯定是“传对象引用”的方式。这种方式相当于传值和传引用的一种综合。
不可变对象(比如数字、字符或者元组)传值时,采用值传递。可变对象(比如字典或者列表)传值时,采用引用传递。
1 | # 空函数 |
函数的参数
1、必选参数
1 | # 必选参数,也叫位置参数 |
2、默认参数
可以简化函数的调用。设置默认参数时,有几点要注意:
- 怎么使用?当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
- 必选参数在前,默认参数在后。
- 默认参数必须指向不变对象,不然是个坑。
1 | # 默认参数,n默认等于2 |
3、可变参数
如不使用可变参数,可以传入序列。
1 | # 传入序列 |
形式为*parameter,允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
1 | def calc(*numbers): |
单星号*的另一个用法是解压参数列表。需要区分。
1 | def foo(bar, lee): |
4、关键字参数
形式为**parameter。允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
1 | def person(name, age, **kw): |
5、命名关键字参数
- 对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。如果要限制关键字参数的名字,就可以用命名关键字参数。
- 命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。
- 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了。
1 | # 命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。例如,只接收city和job作为关键字参数。 |
6、参数组合
- 在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。
- 但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
- 对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。
- 虽然可以组合多达5种参数,但不要同时使用太多的组合,否则函数接口的可理解性很差。
7、lambda匿名函数
1 | import math |
作用域
在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过下划线”_”的前缀来实现的。
当局部变量和全局变量重名时,对函数体变量进行赋值不影响函数体外的变量。但在函数体内使用global关键字修饰后,该变量变为全局变量则会影响。
类
封装、继承、多态。
类的成员有实例方法和数据成员组成。数据成员分为类属性和实例属性。
- 类属性是类中定义的变量,类属性可以通过类名称或者实例名访问,还可以动态地为类和对象添加、修改属性。
- 实例属性是类的方法中的属性,只作用于当前实例。通过实例名称修改实例属性后,不影响该类的另一个实例中实例属性的值。
访问限制,Python没有对属性和方法的访问权限进行限制,为了保证类内部的某些属性或方法不被外部访问,可以在属性或方法名前添加:
- 单下划线,protected保护,允许类本身和子类访问,可以通过类的实例访问。
- 双下划线,private私有,只允许定义该方法的类本身访问,不能通过类的实例访问,可以通过“类的实例名._类名__xxx”方式访问。
- 首尾双下划线,供特殊方法使用,如__init__。
1 | class Student(): |
创建用于属性的计算
1 | class Rect: |
继承
1 | class ClassName(baseclasslist): |
子类可直接重写父类的方法,但在子类中定义__init__()方法时,不会自动调用基类的__init__()方法,需要调用super().__init__()来执行。
多态
对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。
对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
异常
异常 | 说明 |
---|---|
SynatxError | 语法错误 |
NameError | 没有声明的变量引发的错误 |
IndexError | 索引超出序列范围 |
IndentationError | 缩进错误 |
ValueError | 缩进错误 |
IndentationError | 传入的值错误 |
KeyError | 不存在的字典关键字 |
IOError | 输入输出错误 |
ImportError | 无法导入模块或名称时的错误 |
AttributeError | 未知的对象属性错误 |
TypeError | 类型不合适错误 |
MemoryError | 内存不足 |
ZeroDivisionError | 除数为0错误 |
1 | try: |
四、模块
模块,实现某一特定功能的代码放置在一个文件中作为一个模块,可以避免函数名和变量名冲突,提高代码的可维护性。
可使用import modulename [as alias]语句来导入模块。自动创建新的命名空间。
可使用from modelname import member语句来导入模块,直接将具体的定义导入到当前的命名空间中,可用*号导入模块的全部定义。
模块搜索目录的顺序为:当前目录、PYTHONPATH目录、Python默认安装目录。可通过sys.path.append临时添加目录,也可增加.pth文件(推荐),也可创建系统环境变量PYTHONPATH指定。
以主程序的形式执行,需要添加如下,当模块是被导入时不会被执行。
1 | if __name__ == '__main__': |
包
使用模块可避免函数名和变量名重名引起的冲突,但当模块名重复时,可引入Python Package。它是一个文件夹,且有一个名为”__init__.py”的文件。
使用包时,通过如下几种形式导入
1 | import packagename.modulename |
标准模块和第三方模块
Python提供了200多个内置的标准模块。
第三方库都会在Python官方的pypi.python.org网站注册,要安装一个第三方库,必须先知道该库的名称,可以在『官网pypi』或『阿里云pypi镜像』上搜索,比如Pillow的名称叫Pillow,因此,安装Pillow的命令就是:
1 | $ pip3 --version |
- 游戏,可使用第三方模块Pygame。
- GUI,有以下第三方模块:wxPython或PyQt
- 二维码生成,可使用myqr
五、持久化
文件
各种mode区别,+代表读写模式,r为读模式,w为写模式,a为追加模式
mode | 文件存在 | 文件不存在 | 读 | 写 | 流位置 |
---|---|---|---|---|---|
r | 读取文件内容 | 错误 | √ | × | begin |
w | 清空文件内容 | 创建 | × | √ | begin |
a | 保留原始内容 | 创建 | × | √ | begin/end |
r+ | 读写文件内容 | 错误 | √ | √ | begin |
w+ | 清空文件内容 | 创建 | √ | √ | begin |
a+ | 保留原始内容 | 创建 | √ | √ | begin/end |
1 | #mode为w、w+、a、a+时不存在的文件可自动创建,a为追加,w为覆盖 |
目录
1 | import os |
数据库
sqlite
1 | import sqlite3 |
mysql,使用PyMySQL第三方模块
1 | import pymysql |
六、Web开发
Web框架
框架的常用功能
- 管理路由
- 访问数据库
- 管理会话和Cookies
- 创建模板来显示HTML
- 促进代码重用
常用框架
- Django
- Flask
- Bottle
- Tornado
Flask
1 | from flask import Flask,url_for,render_template |
Django
『Django官网』,可以把文档中快速入门教程看一遍。
框架优点:
- 高度定制的ORM
- 大量API
- 简单灵活的视图编写
- 快速开发的模块
- 强大的后台管理
1 | $ python manage.py help |