第一章 Python入门导学
1.1 Python导学
- python不是一门新兴语言,上世纪90年代就已经存在。随着人工智能和大数据的火热,Python随着成为主流编程语言
- 以Python为技术主导的公司:豆瓣、知乎
- Python更像一个技术的润滑剂,大多数互联网公司或多或少都是会使用
- 使用Python3.6版本,从基础语法到复杂高阶函数
1.2 Python特征
- 语法简洁,优雅,人生苦短,我用Python
- 易于学习,
- 万金油语言
- 即为强大的标准库和第三方库
- Python是面向对象的语言
1.3 我为什么喜欢Python
- 简洁、灵活、优雅,java给人的感受是字正腔圆,大气端正
- 易于上手难于精通
- Python既有动态脚本的特性,又有面向对象的特性(Java是要编译的,Python是可以动态执行的,但是没有Java严谨和工整,不用规范变量类型等)
1.4 Python缺点
- 慢,相对于C,C++,Java
(编译型语言C,C++)由编译器编译成机器码
(解释性语言javascript,python)由解释权解释语言
(Java应该被分为在编译基础上进行解释的语言,由编译器编译成字节码,更贴近计算机能直接识别的机器码,需要编译器编译,需要解释器执行)
(为什么有了编译型语言,还要开发解释型语言呢?
运行效率,与开发效率不同)
(语言没有好与坏,只有合适不合适)
1.5 一个经典误区
- 编程 ?= web编程 肯定不是呀,编程不等于开发网站或APP
- Python的应用场景是非常多的
- web是基础,网站开发只是web的一部分
1.6 Python都能做什么(万金油语言)
- 爬虫(搜索引擎,新闻资讯)
- 大数据与数据分析(spark)
- 自动化运维与自动化测试
- web开发:flask,django(读音:粘钩)
- 机器学习:tensorflow
- 胶水语言:能够将其他语言制作的模块很轻松联系在一起
1.7 课程内容与特点
- 基础语法
- Pythonic,比如:变量值交互, x,y = y,x
- Python高性能与优化,选择性能最高,又易于理解的写法
- 数据结构,使用Python实现一些常见的数据结构
- 迷失在了技术海洋之中,回归语言本质,不精进,否则就是会瓶颈
1.8 Python的前景
第二章 Python环境安装
2.1 Python学习建议
- (具体情况)进阶书籍《流畅的Python》
- (不推荐)大量习题 python oj
- 如何继续学习 :数据分析(工具、框架、库是辅助,最主要的是数据模型的建立,所以是数学功底)
AI人工智能(Python只是操作工具而已,最主要的是算法和数据模型)
Python工作中实现场景,比如自己写个小工具,推荐是搜索具体的库来实现
2.2 Python版本选择
- 稳定版,3.6,3.8(建议),日常开发,3.6版本就足够了
- Mac 中内置了Python2
2.3 Python多版本问题
2.4 Python Mac 版本指定
- 问题是Mac自带Python2,这样Python2就是默认版本
- 切换到Python3
1.默认是python + 文件名,这样Mac调用Python2
所以要用Python3 + 文件名
2.虚拟环境
3.系统默认的Python版本更换成Python3
- 或将Python2卸载
- pylint 自动规范化工具
2.5 下载Python安装包
- Mac下载Python3.8 pkg包
- 安装
- 因为我的电脑里,有自带的2.7,竟然还有3.7版本,而且3.7我还删不掉,使用python -V (2.7) python3 -V (3.7)python3.8 -V (3.8)
- 所以我修改python ,默认指向3.8
(1)修改.bash_profile文件
vi ~/.bash_profile
PATH="/Library/Frameworks/Python.framework/Versions/3.8/bin:${PATH}"
export PATH
(2)修改 bashrc文件
sudo vi ~/.bashrc //mac下需要管理员才能修改此文件
alias python2='/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7'
alias python3='/Library/Frameworks/Python.framework/Versions/3.8/bin/python3.8'
alias python=python3
//添加以上三行 , 如果不知道自己的python3安装路径,可以用 which python3 命令进行查看路径
(3)修改的 bash_profile文件 和 bashrc文件 生效
source ~/.bash_profile
source ~/.bashrc
(4)查看Python当前版本
python -V //3.8.2
2.6 安装Python
2.7 IDLE和第一行Python代码
- IDLE是window安装包自带的工具
- Python没有 分号 花括号,主要是利用缩进控制代码格式
第三章 Python基本数据类型
Python3六种数据类型
分为两类:不可变数据(number,string,tuple)可变数据(list,dictionary,set)
可变数据类型:当该数据类型对应变量的值发生变化时,对应内存地址并没有开辟新的内存,而是在原来的内存值上进行修改。
不可变数据类型:当该数据类型对应变量的值发生变化时,原来内存中的值不变,而是会开辟一块新的内存,变量指向新的内存地址。
number(数字)
string(字符串)
List(列表)
Tuple (元组)
set (集合)
Dictionary(字典)
数字 number
- 整数 int 浮点数 float 布尔 bool 复数 complex
- python中没有单精度(float)和双精度(double)
- 其他语言,整数int又分为short,int,long,Python中没有
- type(2/2)得到的是float,单斜杠自动转型成浮点
- type(2//2)得到的是int,双斜杠是整除
- 二进制 0b10 => 2
0b11 => 3
- 八进制 0o10 => 8
0o11 =>9
- 十六进制 0x10 =>16
0x1F => 31
- Python中,转成二进制,使用bin()
- Python中,转成十进制,使用int()
- Python中,转成十六进制,使用hex()
- Python中,转成八进制,使用oct()
字符串 string
- 字符串拼接 +
- 字符串截取 ‘hello world’[1]
- 字符串截取 ‘hello world’[0:5](开始位置到结束位置-1) [0:-1]表示第一个元素到倒数第二个元素的切片
列表 list
元组
集合
- 集合是无序的、不重复的元素序列
- 可以使用{} 或 set()函数来创建集合
- 注意:创建空集合只能是set(),因为{}默认是创建空字典
- 集合虽然定义是不重复的,但是你赋值了重复值,输出的依然是不重复值
''' 集合基本操作 '''
s.add(x)
s.update( x )
s.remove(x)
s.discard(x)
s.pop(x)
len(s)
s.clear()
x in s
str = [1,2,3,4,5,6,7]
str_new = [1,2,2,3,4,5,4]
def unique(seq):
if len(str) == len(set(str)):
print('该列表中元素是唯一的')
else:
print('该列表中元素不唯一')
字典
- {}
- key:value
- 不允许同一个键出现两次
- 键必须不可变,所以可以用数字,字符串或元组充当,而用列表、集合就不行
第四章 变量与运算符
变量
- 命名有意义,可读性要强
- 变量命名规则:字母、数字、下划线组成,首字母不能为数字
- 系统保留关键字不能用作变量名
值类型与引用类型
- 值类型:不可变类型(int,string,tuple)
- 引用类型:可变类型(list,set,dictionary)
- 如果在元组中的列表,是可以改变的(1,2,[3,4])
a = 'hello'
a = a + 'world'
b = 'python'
b[0] = 'b'
b = 'php'
$a = 'php';
$a[0] = 't';
print($a);
列表的可变与元组的不可变
运算符
- 算术运算符
+ 加
- 减
* 乘
/ 除
// 整除
% 取余
** 幂
2.赋值运算符
=
+=
*=
/=
%=
//=
Python中没有自增自减运算符++ –
3.关系运算符
==
!=
>
<
>=
<=
4.逻辑运算符
and 且
or 或
not 非
5.成员运算符
in
not in
字典类型判断是key
6.身份运算符
is (比较的是内存地址)
is not
7.位运算符 (把数字当做二进制数来进行运算)
& 按位与
| 按位或
^ 按位异或
~ 按位取反
<< 左移动
>> 右移动
a = {1,2,3}
b = {2,1,3}
a == b
a is b
a = (1,2,3)
b = (2,1,3)
a == b
a is b
运算符 |
描述 |
** |
指数(优先级最高) |
* / % // |
乘 除 取余 取整 |
+ - |
加减运算 |
>> << |
右移左移运算符 |
& |
位and |
^ | |
位运算符 |
<= >= > < |
比较运算符 |
<> != == |
等于运算符 |
= %= /= //= += -= |
赋值运算符 |
is is not |
身份运算符 |
in not in |
成员运算符 |
not and or |
逻辑运算符 |
第五章 分支、循环、条件、枚举
vscode开发环境与Python插件安装
- 打开控制面板 ctrl + ~
- 搜索 command + shift + p
- sinnpt 代码片段,快速构建代码,直接编辑不用删除,tab跳转到下一个代码块,shift+tab 调到上一个
注释等语法
- 单行注释 #
- 多行注释 ‘’‘
- Python是不可以压缩的,因为是通过空格来辨别语法
- 变量命名,不要使用驼峰,而是用下划线user_passwd
流程控制-条件控制
常量与pylint规范
while
for in 与 for else
- 主要用在遍历、循环 序列或者集合、字典
- for in 类似php foreach
- 注意break,continue
continue是此次循环,下面还会运行
break是结束本次循环,如果外面还有一层循环,是可以正常运行
a = [['apple','banana','orange'],(1,2,3)]
for x in a:
for y in x:
print(y)
for 与 range
for x in range(0,10,2):
print(x,end=' | ')
第六章 包、模块、函数、变量作用域
6.1 包、模块、类
- 包(类似文件夹)>>模块(类似文件)>>类(函数、变量)
- 在Java,PHP中,一个文件最好只写一个类,并且类名和文件名是一致的。但是Python中,类是写在模块中,所以可以写多个类
- 让一个普通文件夹成为一个包,那么包下必须含有__init__.py文件
6.2 import 导入模块 和 from import 导入模块
- Python中的命名空间,要在理解下
- 包和模块是不会被重复导入的,第一次导入就会将模块名加载到内存中,后续的导入仅仅是对加载到内存中的模块增加了一次引用,不会在重新执行import语句
- 避免循环调用
import pylearn.helloworld.py as learn
print(learn.username)
from pylearn.helloworld.py import username
print(username)
6.3 init.py 的用法
6.4 模块内置变量
- 通过 dir() 查看所有变量
- 入口文件和普通模块内置变量是有区别的
#内置变量
__name__ #命名空间,包名+模块名
__package__ #包名
__FILE__ #模块的路径
__doc__ #表示模块中的注释
6.5 再深入理解顶级包的概念
- 入口文件不可用使用相对路径导入模块
- 7-7到7-15可多看
第七章 Python函数
7.1 函数定义及特点
def get_userinfo(username,password):
return username,password
return (username,password)
username,password = getuserinfo('laravelvue','123')
7.2 序列解包与链式赋值
- 序列解包,可以是list,set,tuple
- 序列封包:程序把多个值赋给一个变量时,Python会自动将多个值封装成元组
- 序列解包:程序允许将序列(字符串、元组、列表等)直接赋值给多个变量,此时序列的各元素会被依次赋值给每个变量(要求序列的元素个数和变量个数相等)
res = 1, 2, 3
print(res)
print(type(res))
x, y, z = res
x,y,z = 1,2,3
7.3 函数参数
- 形参
- 实参
- 关键字参数,是为了提高代码可读性
- 默认参数
- 可变参数
- 关键字可变参数
def get_userinfo(username,password):
pass
get('laravelvue','123')
get(username='laravelvue',password='123')
def get_ipinfo(ip,address='0.0.0.0')
def get_equipmentinfo(*param)
get_equipmentinfo('app','mobile')
info = ('wxapp','mobile')
get_equipmentinfo(*info)
def city_temp(**param):
for key,value in param.items():
print(key,':',value)
city_temp(bj='31c',sh='36')
info = {'bj':'31c','sh':'36c'}
city_temp(**info)
7.4 变量作用域,全局变量,局部变量
- 函数体里可以使用全局变量,函数体外不可使用局部变量,但也不绝对,看具体函数
c = 10
def demo():
print(c)
for i in range(0,9):
a = '未预定义变量'
c += i
print(a)
print(c)
c = 1
def func1():
c = 2
def func2():
c = 3
print(c)
func2()
func1()
7.5 global 全局变量
- 可以在外部调用内部的局部变量(当然加上global就是全部变量了)
- global定义全局变量
global db
db = 'mysql'
第八章 面向对象
8.1 类的定义
- python实例化类,不用new ,直接调用即可
student = Student()
而且通过.来调用方法,而不是->
- 字符串拼接用+很像js
- 类中方法,括号中要加self
- 类的最基本作用,封装代码
class Student():
name = 'laravelvue'
homework = 'python'
def student_homework(self):
print(self.name,'|',self.homework)
student = Student()
student.student_homework()
8.2 函数与方法的区别
- 没有绝对区别。在类中更多的应该叫方法,如果在一些公共文件中编写的,应该叫函数。
- 类下的变量的 我习惯叫成员属性,python叫数据成员
8.3 类、对象和实例化
8.4 构造函数
class Student():
name = 'laravelvue'
homework = 'python'
def __init__(self,name,homework):
self.name = name
self.homework = homework
def student_homework(self):
print(self.name,'|',self.homework)
student = Student('laravelchen','python')
print(student.homework)
8.5 区别 类变量 与实例变量
- 类变量–相当于成员属性
- 实例变量–就是对象的变量
- 类变量与实例变量查找顺序–刚开始是会在实例中查找,如果没有会在父类中查找,如果没有会去查找类变量
8.6 self 与实例方法
- self实质是一个指向实例本身的引用
- 形参self比不可少,必须位于其他形参之前。
- 解释self:例如python 在调用__init__构造函数创建实例时,将自动传入实参self。每个与类相关联的方法调用都自动传递实参self,self实质是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
- self就像PHP、Java中的this
- 只是Python中的self必须在形参中强制要求写出来,叫显示调用,像PHP的this就不用写,可以直接用,叫隐式调用
8.7 类方法,静态方法,实例方法
- Python面向对象过程中,类属性可细分为类属性和实例属性,那么类中的方法可分为 类方法、实例方法、静态方法
- 实例方法:一般情况下类中定义的方法/函数默认是实例方法
实例方法最大的特点就是最少含有一个self参数,该self参数是为了绑定调用此方法的实例对象
- 类方法:
①类方法至少包含一个参数,默认cls
②Python会自动将类本身绑定到cls参数,所以在调用类方法时,无需显式为cls参数传递参数
③类方法需要使用装饰器 @classmethod
- 静态方法:
①静态方法没有slf,cls这些特殊形参,故Python解释器不会对其包含的参数做任何类或对象的绑定
②通过类直接调用,不需要创建对象
③静态方法主要用于存放逻辑性的代码,主要是一些逻辑属于类,但是和类本身没有交互。所以在静态方法中,不会涉及到类的属性和方法的操作
@classmethod
def get_info(cls):
pass
@staticmethod
def add(x,y):
pass
def __get_user(self):
pass
8.9 访问控制 public,private,protected
- 通过成员方法来修改成员属性
- Python没有private和public,直接在前面设置双下划线__表示私有方法和属性
8.10 继承
- 多继承
- from import文件之后,在类名括号中引入父类
class Student(Homuman)
PHP中是继承分为两步,第一use引入;第二extends继承
- super是子类用来调用父类方法的
- 子类和父类方法重名,默认会执行子类方法
其实下面的代码是Python2的继承方式
super(Student,self).dohomework()
第九章 正则表达式与JSON
9.1 Python中使用正则表达式
‘’‘ 引入Python正则库 ’‘’
import re
str = 'Python|PHP|Java|C|C++'
res = re.findall('Python',str)
res = str.index('Python')
print('Python' in str)
if len(res) >0 :
print('Yes')
else:
print('No')
9.2 正则表达式规则
模式 |
描述 |
^ |
匹配字符串开头 |
$ |
匹配字符串结尾 |
. |
匹配任意字符,除了换行符 |
[…] |
用来表示一组字符,[abc]匹配a或b或c |
[^…] |
不在[]中的字符,[^abc]匹配除了abc的其他字符 |
re* |
匹配0个或多个表达式 |
re+ |
匹配一个或多个表达式 |
re? |
匹配0个或一个符合前面正则表达式片段,非贪婪模式 |
re{n} |
匹配n个前面正则表达式 |
re{n,} |
精确匹配n个前面正则表达式,a{1,}相当于a+,a{0,}相当于a* |
re{n,m} |
匹配n到m次由前面的正则表达式匹配的片段,贪婪模式 |
a|b |
a或b |
(re) |
匹配括号内的表达式,也表示一个组 |
\w |
匹配数字字母下划线 |
\W |
匹配非数字字母下划线 |
\s |
匹配任意空白字符,相当于[\t\n\r\f] |
\S |
匹配任意非空字符 |
\d |
匹配任意数字,相当于[0-9] |
\D |
匹配任意非数字 |
- * 匹配0次或无限次
- + 匹配1次或无限次
- ? 匹配0次或1次
- [] 中括号之间是或关系
- () 小括号之间是且关系
9.3 re.sub()正则替换
- re.sub(正则规则,替换成的字符,原始字符串,替换次数0是无限次)
import re
str = 'A12CED23412398075'
def convert(value):
matched = value.group()
if int(matched) >= 6:
return '9'
else:
return '0'
res = re.sub('\d',convert,str)
print(res)
9.4 re.search()和re.match()
- search与match之匹配一次,非贪婪
- findall会自动匹配所有
9.5 group分组
9.6 JSON,序列号,反序列号
- web时代-移动端时代-AI时代
- 反序列号,从json到Python或某个语言转换
- 序列号,Python转化成json
import json
json_str = '{"name":"laravelvue","age":18}'
json_arr = '[{"name":"laravelvue","age":18},{"name":"lc","age":18}]'
student1 = json.loads(json_str)
student2 = json.loads(json_arr)
json |
python格式 |
object |
dict |
array |
list |
string |
str |
number |
int |
number |
float |
true |
True |
false |
False |
null |
None |
9.4 json 、json对象、json字符串
第十章 Python高级语法与用法
10.1 枚举是一个类
- 数字表示类型,破坏了代码的可阅读性,表示数据库里是可以的
- 很多语言中,枚举是一个数据类型,而不是一个类
- 枚举类和普通类的区别
''' 模拟枚举类型的三种方法 '''
yellow = 1
black = 2
{'yellow':1,'black':2}
class TypeDiamond():
yellow = 1
black = 2
'''
通过字典、类模拟枚举,有一下缺点
1.数据是可变的,通过代码很容易修改
2.不能防止重复性
'''
''' 引入enum类库 '''
from enum import Enum
class Vip(Enum):
YELLOW = 1
BLACK = 2
print(Vip.YELLOW)
print(Vip.YELLOW.name)
print(Vip.YELLOW.value)
- 枚举可以进行等值比较,不能做大小比较,
- 枚举转换 ,将数值转成名称
a = 1
name = Vip(a)
- 如果想要枚举里数据不能重复,可以在类前添加装饰器
@unique
- 枚举类是不能实例化的,因为是单例模式
10.2 闭包
- 基础知识能让我们写出代码,但不能让我们写出优质代码
- 业务逻辑的开发者,不要考虑太多的封装性
- 但是如果是包和类库的开发者,封装性要求高
- 函数式编程
- Python一切皆对象
- Python中函数可以作为一个返回结果被返回
- Python中函数可以赋值给一个变量
def add():
def addall():
pass
return addall
f = add()
- 闭包 = 函数 + 环境变量,把函数调用时的现场进行了保存
def f1():
a = 10
def f2():
a = 20
print(a)
print(a)
f2()
print(a)
f1()
''' 理解闭包 '''
def f1():
a = 10
def f2():
a*20
return f2
f = f1()
print(f.__closure__)
- 记录一个人的步数,每次记录的步数要保存,并进行累加。
比如,初始0步,依次走2,5,6步,输出2,7,13步
''' 引用全局变量 '''
origin = 0
def go(step):
global origin
origin += step
return origin
print(go(2))
print(go(3))
print(go(6))
''' 闭包函数 '''
pos = 0
def tourist(pos):
def go(step):
nonlocal pos
new_pos = pos + step
pos = new_pos
return new_pos
return go
go = tourist(0)
print(go(2))
print(go(3))
print(go(5))
''' 面向对象,调用类变量 '''
class move():
origin = 0
def go(self,step):
self.step = step
new_position = move.origin + step
move.origin = new_position
return new_position
f1 = move()
r1 = f1.go(2)
r2 = f1.go(3)
r3 = f1.go(4)
print(r1, r2, r3)
第十一章 函数式编程、匿名函数、高阶函数、装饰器
11.1 匿名函数
def add(x,y):
return x+y
lambda x,y:x+y
11.2 Python的三元表达式
- Python没有像其他语言那样的专门三元表达式,而是利用if else
- 三元表达式经常适用于 匿名函数 中
x > y ? x :y
x if x > y else y
11.3 map 类
- map类,相当于for循环,将传入的第二参数(列表、集合)中的每个元素,都去调用传入的第一个参数(函数)
list_x = [1,2,3,4,5,7,9]
def square(x):
return x*x
’‘’ 常规思路 可以for循环 ‘’‘
for i in list_x:
return square(i)
’‘’ 使用map简化代码 ‘’‘
list_y = list(map(square,list_x))
11.4 map与lambda
- map与lambada结合,可以使用匿名函数代替传入的第一个参数(函数)
- map 和lambda不能提高代码的执行效率,仅是调高了代码的阅读性,让代码更简洁,当然你要能看到map和lambda
list_x = [1,2,3,4,5,7,9]
list_y = [1,2,3,4,5,6,7]
r = map(lambda x,y:x*x+y,list_x,list_y)
11.5 reduce
11.6 filter
11.7 命令式编程 与 函数式编程
- 命令式编程一些关键词,帮助理解,def if … else for … in
- 函数式编程一些关键词,帮助理解,map reduce filter lambda
11.8 装饰器
- 设计原则之一:开闭原则–对修改是封闭的,对扩展是开放的
- 思想:代码稳定性和复用性,想给一个函数增加一个功能,但是不想改变函数的内部实现,那么可以通过装新功能写成装饰器,每个地方调用的时候调用它,就OK
- 适用:
import time
def decorator(func):
def wrapper():
print(time.time())
func()
return wrapper
@decorator
def f1():
print('This is a function')
f1()
- 善于利用空行来进行区分代码块,让代码块结构更清晰
- 不要在一个函数、一个类里写太多代码,函数体积越小就越灵活,就越有可能被复用,建议一个函数行数控制在10-20行之间