Python学习笔记
Python学习笔记
1.python基础
1.1python语法常识
- python语法采用缩进格式而不是括号来进行代码块分割的
- 缩进没有空格个数或者
tap
键的约束,但应坚持使用四个空格缩进- 当语句以
:
结尾时,缩进的语句视为代码块- 以#开头的是注释
- 复制粘贴功能基本等于失效,粘贴的代码必须检查缩进是否正确
- python是大小写敏感的,写错了大小写,程序会报错
1 2 3 4 5 6
#print a = 100 if a >= 0: print(a) else: print(-a)
1.2基本数据类型
1.2.1数据类型分类
1.2.1.1数字型与非数字型
python
中的变量一般分为两种类型 数字型和非数字型- 数字型
- 整型
- 浮点型
- 布尔型
- 复数型
- 非数字型
- 字符串
- 列表(list)
- 元组(tuple)
- 字典(dict)
1.2.1.2不可变类型与可变类型
python
中变量都是通过对数据的引用来定义的。不可变类型只能在内存中重建一组数据,然后让变量指向数据
可变类型直接可以改内存中定义好的数据
给变量赋新值是改变变量指向的地址
通过方法改变数据的值不影响变量指向的地址
- 不可变类型
- 数字类型
- 字符串
- 元组
- 可变类型
- 列表
- 字典
- 哈希函数
hash
- 接收一个不可变类型作为参数
- 返回值是一个整数
python
中设置字典键值对时,会首先对key
进行hash()
决定数据如何在内存中保存,方便之后的增删改查- 键值对的
key
必须是不可变类型 - 键值对的
value
可以是任何类型
- 键值对的
1.2.2基本数据类型介绍
-
python
是动态语言变量本身类型不固定 -
整数
- 十六进制前面用**
0x
**例0xff00
python
的整数和浮点数没有大小限制/
结果是精确的,//
是除法结果取整,%
是取余
- 十六进制前面用**
-
浮点数
1.23*10^9
等于1.23e9
- 浮点数有误差
-
字符串
-
用
''
或""
扩起来的任意文本 -
转义字符
\
-
可以用
r''
表示''
内部的字符串默认不转义 -
字符串内部有多个换行,写在
\
中不好阅读'''...'''
表示多行内容...
是提示符,不是代码的一部分,不需要手打
1 2 3 4 5 6
print('''line1 ...line2 ...line3''') line1 line2 line3
1 2 3 4
print(r'''hello,\n world''') hello,\n world
-
-
布尔
True False
and or not
运算3>2
输出True
-
空值
None
表示空值
-
常量
-
变量
python
是动态语言- 首先在内存中创建值,然后将变量指向该值
x = y
是把变量x
指向真正的对象,y
改变不影响x
的值
1.3运算符
1.3.1算术运算符
运算符 | 描述 |
---|---|
** | 乘幂 |
+ | 加法 |
- | 减法 |
/ | 除法 |
* | 乘法 |
// | 取整数 |
% | 取余 |
*
还可用于字符串,结果是将运算符重复n次运算符优先级与C语言类似。可以通过
()
来增加优先级
1.3.2赋值运算符
运算符 | 描述 | 实例 |
---|---|---|
= | 赋值 | c = a |
+= | 加法赋值 | c += a c = c + a |
-= | 减法赋值 | c -= a c = c - a |
/= | 除法赋值 | c /= a c = c / a |
*= | 乘法赋值 | c *= a c = c * a |
//= | 取整数赋值 | c //=a c = c //a |
%= | 取余赋值 | c %= a c = c % a |
**= | 幂赋值 | c **= a c = c ** a |
1.3.3比较运算符
运算符 | 描述 | 举例 |
---|---|---|
== | 等于判断 | a==b |
!= | 不等于判断 | a!=b |
> | 大于判断 | a>b |
< | 小于判断 | a<b |
>= | 大于等于判断 | a>=b |
<= | 小于等于判断 | a<=b |
结果为True和False
1.3.4逻辑运算符
运算符 | 描述 | 举例 |
---|---|---|
and | if x is false, then y, else x | a and b |
or | if x is false, then x, else y | a or b |
not | if x is false, then True , else False |
not a |
1.3.5位运算符
运算符 | 描述 | 举例 |
---|---|---|
| | 按位与 | a | b |
^ | 按位异或 | a ^ b |
& | 按位与 | a&b |
« | 左移 | a«b |
» | 右移 | a»b |
~ | 按位取反 | ~a |
1.4字符串和编码
1.4.1字符串和编码总览
- ASCII编码是一个字节,表示数量有限
- Unicode编码是两个字节,但是空间多一倍
- UTF-8可变长,把一个Unicode字符编码成1-6个字节。英文是一个字节,汉字通常三个字节,大量英文就能升空间。
- 本地计算机中存储用UTF-8,内存中用Unicode,需要时互相转换
- 浏览网页,服务器Unicode,转换成UTF-8到网页
1.4.2python的字符串
python字符串是以Unicode
来编码的
ord('A')
可获取字符的整数表示
|
|
- **
chr(66)
**把整数表示转换为对应的字符
|
|
.encode()
将字符串用特定编码方式转换为字节输出。- **
.decode
**将字节读入的字符串按特定编码方式输出
|
|
len()
计算字符串的字符数,如果是字节表示的,就计算字节数
|
|
-
python文本文件储存和读取格式
- 指定python读取格式
1 2
#!/usr/bin/env python3 # -*- coding: utf-8 -*-
- 指定python储存格式
储存格式需要通过编辑器指定
-
python字符串格式化的第一种形式
- 与C语言一致,通过
%d%f%s%x
指定
1 2 3 4
>>> 'hello,%s' % 'world' 'hello,world' >>> 'Hi,%s,you have $%d'%('Michael',1000) 'Hi,Michael,you have $1000'
- 不知道应该用什么,
%s
永远起作用
- 与C语言一致,通过
-
python字符串格式化的第二种形式
1 2 3 4 5 6
>>> 'Hello,{0},成绩提升了 {1:.1f}%'.format('小明',17.125) 'Hello,小明,成绩提升了 17.1' >>> str = 'Hello,{0},成绩提升了 {1:.1f}%' >>> print(str.format('小明',17.125)) 'Hello,小明,成绩提升了 17.1'
1.5条件判断语句
|
|
1.6循环语句
|
|
1.7高级数据类型
1.7.1变量的分类与简介
1.7.1.1数字型与非数字型
-
python
中的变量一般分为两种类型 数字型和非数字型 -
数字型
- 整型
- 浮点型
- 布尔型
- 复数型
-
非数字型
- 字符串
- 列表(list)
- 元组(tuple)
- 字典(dict)
-
非数字变量的特点
- 都可以看成一个序列(
sequence
),也可以理解为容器 - 取值
[]
- 遍历
for x in
- 计算长度、大小,最大小值、比较,删除
- 链接
+
和重复*
- 切片
- 都可以看成一个序列(
1.7.1.2可变类型与不可变类型
python
中变量都是通过对数据的引用来定义的。不可变类型只能在内存中重建一组数据,然后让变量指向数据
可变类型直接可以改内存中定义好的数据
给变量赋新值是改变变量指向的地址
通过方法改变数据的值不影响变量指向的地址
- 不可变类型
- 数字类型
- 字符串
- 元组
- 可变类型
- 列表
- 字典
- 哈希函数
hash
- 接收一个不可变类型作为参数
- 返回值是一个整数
python
中设置字典键值对时,会首先对key
进行hash()
决定数据如何在内存中保存,方便之后的增删改查- 键值对的
key
必须是不可变类型 - 键值对的
value
可以是任何类型
- 键值对的
1.7.1.3局部变量与全局变量
- 局部变量在函数内部定义,只在*该函数内部使用**
- 全局变量在函数外部定义,所有函数都可以使用该变量
- 大多数语言不推荐使用全局变量
- 函数在使用变量时,会首先检索局部变量,如果没有局部变量,会检索全局变量
1.7.1.3.1局部变量
- 局部变量是在函数内部定义的变量,只有在该函数内部才可以使用
- 函数执行结束后,函数内部的局部变量会被系统回收
- 不同函数中局部变量可以重名,且无影响
- 局部变量的生命周期
- 生命周期指从被创建到被系统回收的过程
- 局部变量在函数执行时才被创建,函数执行结束后被回收
- 局部变量在生命周期内,可以用来保存函数内部使用到的数据
1.7.1.3.2全局变量
-
全局变量是在函数外部定义的变量,所有函数都可以使用
-
默认函数内部不允许直接修改全局变量的引用,使用赋值语句修改全局变量的值
-
如果使用使用赋值语句修改全局变量的值,会重新定义一个局部变量
-
要在函数内部修改全局变量的名,需要加
global
关键字声明变量 -
应将全局变量定义在所有函数的上方
1 2 3 4 5 6 7
num = 10 def demo1(): global num num = 20 #这样可以修改全局变量 #global关键字会告诉解释器,后面的值是一个全局变量, #再使用赋值语句时,不会再创建局部变量
1.7.2集合类型list(列表)
和tuple(元组)
1.7.2.1list
(类似于空类型集合)
- 列表支持的方法
|
|
list
定义方法(类似于可变数组)
|
|
list
访问方式(与数组类似)
|
|
list
追加元素到末尾
|
|
list
把元素插入特定位置
|
|
list
删除元素
|
|
list
改变元素
|
|
list
元素类型可以是任意的,也可以不同
|
|
list
使用场景- 将多个同类型的元素保存到
list
里,遍历处理
- 将多个同类型的元素保存到
list
类似于Java
的空类型集合list
len()函数可以获得
list
元素的个数
1.7.2.2tuple
(类似与数组,一旦初始化就不能改变)
tuple
支持的方法
|
|
tuple
定义只有一个元素的该类型时,需加一个,
|
|
tuple
虽然不可变,但是包含的List
可以变,因为包含的list
是以指针指向的形式保存的,list
是可变的
|
|
-
元组使用场景
- 函数多个参数和多个返回值,以元组实现
- 格式字符串(%d,%s),以元组实现
1 2 3 4 5 6 7
print('%s, %d' % ('李四',14)) #等于 info_tuple = ('李四',14) print('%s,%d' % info_tuple) #等于 info_str = '%s,%d' % info_tuple print(info_str)
- 让列表数据不被修改
tuple(list)
-
修改
tuple
,可list(tuple)
,修改之后的list
,然后再tuple(list)
1.7.3使用dict
和set
1.7.3.1dict
key
只能使用字符串,数字或者元组- 字典的常用操作
|
|
-
dict
类似与Java
中的map
通过key来映射value,所以key的值只能是不可变量,不能是list类型
字典无序,列表有序
- 创建和使用
|
|
- 放入数据
|
|
- 改变数据
|
|
- 查询是否存在
|
|
- 删除数据
|
|
- 使用场景
- 将多个字典放在一个列表里,循环遍历处理
1.7.3.2set
-
set
类似与java
中的set
- 创建(需要通过
list
创建)
1 2 3
>>> s = set ([1,2,3,2,3]) >>> s {1,2,3}
- 添加
1
s.add(4)
- 删除
1
s.remove(4)
- 交并
1 2 3 4 5 6
>>> s1 = set([1,2,3]) >>> s2 = set([2,3,4]) >>> s1 & s2 {2,3} >>> s1 | s2 {1,2,3,4}
- 创建(需要通过
1.7.4字符串
- 因为大部分变成语言字符串都是双引号,尽量使用
双引号
定义字符串 - 可以使用
for
循环来访问字符串的每个字符
字符串的常用操作,可以查文档
|
|
1.7.5高级数据类型公共方法
1.7.5.1公共函数
函数 | 描述 | 备注 |
---|---|---|
len(a) | 计算容器中元素的个数 | |
del(a) | 删除变量 | 注意与关键字区分 |
max(a) | 返回容器中的最大值 | 如果是字典,仅针对key值 |
min(a) | 返回容器的最小值 | 如果是字典,仅针对Key值 |
1.7.5.2切片(字符串,元组,列表支持,字典不支持)
- 切片使用索引值来从较大容器中切出小容器。
1.7.5.3运算符
列表中使用
+=
运算符会直接调用列表的extend()
方法列表中先相加再赋值,并不会调用
extend()
方法
运算符 | 举例 | 结果 | 描述 | 支持的数据类型 |
---|---|---|---|---|
+ | [1,2]+[3,4] | [1,2,3,4] | 合并 | 字符串,元组,列表(生成一个新的) |
* | [“Hi”]*4 | [“Hi”,“Hi”,“Hi”,“Hi”] | 重复 | 字符串,元组,列表 |
in | 3 in(1,2,3) | True | 元素是否存在 | 字符串,元组,列表,字典(字典中,必须要用key) |
not in | 3 not in(1,2,3) | False | 元素是否不存在 | 字符串,元组,列表,字典 |
>,>=,<,<=,== | (1,2,3)<(2,2,3) | True | 元素比较 | 字符串,元组,列表 |
- 成员运算符
in
和not in
2.函数
- 定义函数
|
|
- 函数参数
在python中类型属于对象,变量没有对象
a = [1,2,3]
中,[1,2,3]
是List类型,而a
没有类型
a
仅仅是对象的引用(一个指针)在python中类型分为可变类型和不可变类型
- 可变类型:list,dict等
- 不可变类型:None,Strings,numbers,tuples等
不可变类型赋新值时是创建一个新对象,然后抛弃原来的对象
a = 10然后a = 5,实际上是新创建一个对象5,让a指向5,丢掉原来的10
可变类型直接更改对象
la = [1,2,3]然后la[2] = 4,实际上是对象[1,2,3]变成[1,2,4]
|
|
2.1函数参数和返回值
函数根据有没有参数和返回值有四种分类
- 有参数,有返回值
- 无参数,有返回值
- 有参数,无返回值
- 无参数,无返回值
1.处理外部数据,加参数
2.需要向外部汇报结果,返回数据,加返回值
2.1.1函数的返回值
-
仅返回一个返回值
return a
result = demo()
-
返回多个返回值
return a1,a2
- 方式一
result = demo()
,result
是tuple元组
类型,单独取值需result[0]
- 方式二
b1,b2 = demo()
,此时b1 = a1
,b2 = a2
使用多个变量接收返回值时,变量的个数应该与返回值个数一样
否则会报错
- 方式一
扩展,交换两个变量
1 2 3
c = a a = b b = c
1 2 3 4
a = a + b b = a - b a = a - b
1 2
#仅python可用的方法 a,b = b,a
2.1.2函数的参数
-
函数参数本质上是在函数内部建立的不能全局化的局部变量(数据引用)
-
可变参数和不可变参数
- 如果在函数内部,在函数内部对变量重新赋值,会创建一个新的局部变量(注意与全局变量和局部变量区分开,函数参数与全局变量一般名字不同,如果名字相同,使用
global
也会报错) - 如果在函数内部,对可变类型调用方法改变可变类型的值,会影响数据本来(外部)的值
列表的
+=
是调用extend()
方法列表的先相加再赋值,不是调用
extend()
方法 - 如果在函数内部,在函数内部对变量重新赋值,会创建一个新的局部变量(注意与全局变量和局部变量区分开,函数参数与全局变量一般名字不同,如果名字相同,使用
2.1.2.1默认参数(缺省参数)
- 给某个参数指定一个默认值,具有默认值的参数叫做缺省参数
- 调用时没有传入缺省参数的值时,会使用默认值
- 使用默认参数(缺省参数),可以简化函数,例如
sort()
函数 - 需要使用最常见的值作为默认值
- 如果值不能确定,则不能使用默认参数
注意事项
- 默认参数应放在所有参数的最后面,即,在默认参数后面,不允许出现未设置默认值的参数,否则会报错
- 默认参数没有按默认顺序输入时,需要把参数名写上,例
1 2 3
def enroll(name, gender, age=6, city='Beijing') 调用enroll('Sarah', 'F',city = 'TianJin') 或enroll('Sarah', 'F',7)
2.1.2.2多值参数(可变参数)
-
有两种情况
- 参数前加
*
,可以传递元组,或者列表,函数将传进去的元组和列表统一变成元组处理 元组列表拆包
,将一个元组或列表变成一组数据,在元组或列表前加*
1 2 3 4 5 6
def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum #此方式可直接如下调用calc(1,2,3,4) 如果有num = [1,2,3],那么直接调用calc(*num)
- 参数前加
**
,可以传递字典 字典拆包
,将一组字典
变成一组数据,在字典前加**
1 2 3 4 5 6 7 8 9
def person(name, age, **kw): print('name:', name, 'age:', age, 'other:', kw) person('Bob', 35, city='Beijing') #结果name: Bob age: 35 other: {'city': 'Beijing'} person('Adam', 45, gender='M', job='Engineer') #结果name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'} extra = {'city': 'Beijing', 'job': 'Engineer'} person('Jack', 24, **extra) #结果name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
- 参数前加
2.2函数递归
|
|
3.高级特性
切片
- 适用对象:
list
,tuple
- 用法
|
|
迭代
|
|
列表生成式
- 运用列表生成式,可以快速生成list,可以通过一个list推导出另一个list,而代码却十分简洁。
|
|
生成器
- 用来保存一种算法
- 获取下一个值使用
next(g)
|
|
迭代器
- 凡是可作用于
for
循环的对象都是Iterable
类型; - 凡是可作用于
next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列; - 集合数据类型如
list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。 - 可以通过
list(Iterrator)
此种方式得到一个Interable
- Python的
for
循环本质上就是通过不断调用next()
函数实现的.
|
|
等价于
|
|
4.函数式编程
特点:允许把函数本身作为参数传入另一函数,还允许返回一个函数
python
中变量可以指向函数python
中函数名也是变量
高阶函数
- 可以把函数作为参数传入的函数称为高阶函数
|
|
map(f,list)
函数把list
中的每个数都按照f
的运算规则计算,得出一个Iterator
|
|
reduce(f,list)
函数把list
中前两个元素按f
计算,再将结果继续和序列的下一个元素进行累计计算
|
|
filter(f,list)
函数函数把list
中的每个数都按照f
的运算规则计算,如果运算结果是True
则保留该元素,否则丢弃该元素。
|
|
sorted()
可以对list
排序,同时也是高阶参数,可以接收一个参数key
来实现自定义排序key
作用于每个数据,然后根据返回的list
进行排序
默认情况下,对字符串排序,是按照ASCII的大小比较的
|
|
5.模块
- 模块需要用
import
关键字导入 - 每一个以
.py
为结尾的文件都是一个python模块
- 模块中定义的
函数
和全局变量
都是一个模块中可以提供给外界直接使用的工具
|
|
-
模块也是一个标识符
- 标识符由字母、下划线和数字组成
- 标识符不能以数字开头
- 不能和关键字重名
-
模块作用域
- 类似
__xxx__
这样的变量是特殊变量,可以被直接引用,但是有特殊用途 - 似
_xxx
和__xxx
这样的函数或变量就是非公开的(private),不应该被直接引用
- 类似
模块规范
|
|
-
第1行和第2行是标准注释,第1行注释可以让这个
hello.py
文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码; -
第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;
-
第6行使用
__author__
变量把作者写进去 -
模块是一个包含Python定义和语句的文件。文件名就是模块名后跟文件后缀
.py
。在一个模块内部,模块名(作为一个字符串)可以通过全局变量__name__
的值获得。
6.面向对象编程
6.1面向对象与面向过程的区别
- 面向对象是对面向过程进一步的封装,不仅封装了相同的方法,还将相同属性封装在了一起
6.2类与对象
6.2.1类与对象的概念
6.2.2类的设计
- 类的命名满足大驼峰原则
- 属性
- 方法
参考面向对象编程的概念
6.3面向对象的基础语法
6.3.1dir
内置函数
python
中,变量,数据,函数都是对象
在python
中可用两种方法验证:
- 在标识符/数据后面输入一个
.
,按下tab
键,会提示方法列表 - 使用内置函数
dir
传入标识符/数据,可以查看对象内的所有属性和方法def demo()
,dir(demo)
提示,
__方法名__
格式的方法是python
提供的内置方法/属性
6.3.2定义简单的类
6.3.2.1定义只包含方法的类
python
中语法格式如下
|
|
- 方法与函数几乎一样
- 方法中的特殊处在于,第一个参数必须是
self