python3基础
一 环境搭建
1.1 安装python(类似于jdk)
- 从python官网下载python安装包
- 安装
1.2 安装软件包
pip install + 软件包名,如:
pip install pandas
二 基础语法
2.1 数据类型
2.1.1 int(整型)
2.1.1.1与Java不同之处:
- 没有长度限制
- 八进制表示:Java以零0开头,python以零0和小写o开头
2.1.1.2 进制转换
得到的是字符串
- 10->2:bin()
- 10->16:hex()
2.1.2 complex(复数)
表现为实部加虚部:a + bj或者a + bJ
例: 2+5j
2.1.3 flout(浮点型)
2.1.4 e记法
5e5,即5乘以10的5次方
2.1.5 bool(布尔)
与Java的不同之处:
- 首字母要大写
- 0可以当做False使用,非0可以当做True使用
i = 5
while i:
print(i)
i -= 1
2.1.6 None(空值)
占位,不表示任何类型
2.1.7 str(字符串)
操作与序列很相似
2.1.7.1 与Java不同
-
可以使用单引号,或者三对单引号,三对双引号。
使用三对引号的时候,会在换行的地方自动添加换行符 \n,不用手动添加换行符 。
如果字符串中有双引号,使用单引号定义字符串,就不用对里面的双引号转义了,反之亦然。 -
raw:原始字符串,即使字符串中的转义失效。比如为了不让路径字符串中的反斜杠 \ 被当成转义字符,就需要在字符串前面加上小写 r 。
path = r'D:\user\data'
2.1.7.2 常用方法
python | Java | 注释 |
---|---|---|
str | new | 创建字符串 |
capitalize | StringUtils.capitalize | 首字母大写 |
casefold | toLowerCase | 全部转换为小写 |
center | StringUtils.center | 字符串居中并在两边填充空格至指定长度 |
count | StringUtils.countMatches | 计算子字符串在目标字符串指定下标范围内出现的次数 |
endswith | endsWith + substring | 字符串在某个下标范围内是否以指定字符串结束 |
expandtabs | 把tab符号(\t)转换为指定数量的空格(默认8个) | |
find | indexOf | 在目标字符串指定下标范围内查找子字符串的下标位置 |
index | indexOf | 与find类似,不过如果找不到会抛异常 |
isalnum | StringUtils.isAlphanumeric | 判断字符串中有字符并且没有字母与数字之外的其他字符 |
isalpha | StringUtils.isAlpha | 判断字符串中有字符并且都是字母 |
isdecimal | matches + 正则 | 判断字符串中有字符并且都是十进制数字 |
isdigit | matches + 正则 | 判断字符串中有字符并且都是数字 |
islower | StringUtils.isAllLowerCase | 判断字符串中有字符并且都是小写字母 |
isupper | StringUtils.isAllUpperCase | 判断字符串中有字符并且都是大写字母 |
isnumeric | StringUtils.isNumeric | 判断字符串中有字符并且都是数字 |
isspace | StringUtils.hasText | 判断字符串中是否只有空格 |
istitle | matches + 正则 | 判断是否为标题,即单词首字母大写,其余小写 |
join | String.join + split | 把当前字符串作为分隔符插入另一个字符串每个字符之间 |
ljust | 左对齐,与center类似 | |
lower | toLowerCase | 全部转换为小写 |
lstrip | 去掉左边的空格 | |
partition | 把字符串转化为大小为3的元组 | |
replace | replace | 替换,可以指定替换几个 |
rfind | lastIndexOf | 从右边开始查找 |
rjust | 右对齐,与center类似 | |
rpartition | 把字符串转化为大小为3的元组,从右边开始查找 | |
rstrip | 去掉右边的空格 | |
split | split | 根据指定符切割转换为元组,默认根据空格切割 |
splitlines | 根据换行符\n切割,返回指定行数 | |
startswith | startWith + substring | 判断字符串在指定下标范围内是否以某个字符串开头 |
strip | trim | 去掉两边的空格 |
swapcase | StringUtils.swapCase | 大小转换为小写,小写转化为大写 |
title | 转换为为标题,即单词首字母大写,其余小写 | |
translate | replace | 替换字符串中所有符匹配的子字符串 |
upper | toUpperCase | 所有字母转换为大写 |
zfill | 右对齐,与rjust类似, 不过左边是用0填充 |
2.1.7.3 格式化
-
format函数
-
百分号
2.1.8 序列
与Java的不同:
- 反向索引:即负数,从 -1 开始。
- 切片:[a: b: c],a为起始下标索引(默认0),b为结束下标索引(默认到最后),c为步长(默认为0)
- 通过(del + 切片)删除
常用方法
python | Java | 注释 |
---|---|---|
max | stream + max | 获取最大值 |
min | stream + min | 获取最小值 |
sum | stream + sum | 从指定下标开始求和 |
sorted | sort | 排序 |
reversed | reverse | 反转 |
enumerate | 把里面每个元素替换为下标与元素组成的2元组 | |
zip | 把多个序列中下标相同的放到一起组成元组,长度取最小的序列 |
序列中的操作符
-
比较操作符
从第一个开始逐个比较,直到遇到不相等的时候比较其大小,后面的不做比较。
如果其中一个与另一个的前面部分完全相同,则长度长的大。 -
运算操作符
+或+=:两边都必须是列表,相当于extend函数,即将两个列表拼接在一起
*或*=:必须乘以整数,即把列表复制几份并拼接在一起 -
成员操作符
判断某个成员(成员可以使数字、列表等)是否在列表中,有 in 与 not in 两个。相当于Java中list的contains方法。
2.1.8.1 list(列表)
相当于Java中的ArrayList
2.1.8.1.1 创建方式
使用中括号创建
l1 = []
l2 = [1, '2']
l3 = list()
l4 = list('hello')
2.1.8.1.2 常用方法
python | Java | 注释 |
---|---|---|
list | new | 创建列表 |
len | size | 获取长度 |
append | add | 添加单个元素 |
extend | addAll | 添加列表 |
insert | add | 在指定位置插入元素 |
remove | remove | 移除元素 |
del | remove + clear | 移除指定位置的元素,也可以删除整个列表,包括变量名 |
pop | get + remove | 获取并移除最后一个(或指定下标)元素 |
test[1: 3] | test.subList(1, 3) | 截取test列表中下标1-2之间的元素作为列表,下标默认从0到最后(可以不填)。subList为浅拷贝,而列表分片为深拷贝 |
count | Collections.frequency(list, key) | 统计列表中某个元素的个数 |
index | indexOf + lastIndexOf + subList | 查找某个元素在列表中第一次出现的位置下标。三个参数分别为要查找的元素、开始下标、结束下标 |
reverse | Collections.reverse(list) | 把列表倒转 |
sort | sort | 排序 |
2.1.8.1.3 切片
x = [2, 3, 4]
x[0: 1] = [100, 200] # x = [100, 200, 3, 4]
x[: 2] = [1, 2] # x = [1, 2, 3, 4]
x[2:] = [100, 200] # x = [1, 2, 100, 200]
x[:] = [0, 1, 2, 3, 4] # x = [0, 1, 2, 3, 4]
x[::2] = [100, 200, 300] # x = [100, 1, 200, 3, 300]
x[::2] = 'asd' # x = ['a', 1, 's', 3, 'd']
2.1.8.1.4 列表推导式
x = [1, 2, 3]
x = [i ** 2 for i in x] # x = [1, 4, 9]
x = [i ** 2 for i in x if i > 1] # x = [16, 81]
y = [1, 2, 3]
z = [i * j for i in x for j in y] # z = [16, 32, 48, 81, 162, 243],每个元素两两相乘
2.1.8.2 tople(元组)
创建
i = ()
i = tople()
i = (1,)
i = (1, 2, 3)
元组是不可变的列表,相当于Java中被final修饰的ArrayList。
如果元组只有一个元素,必须在元素后面带上逗号。
要修改元组,可以根据现有的元组通过分片和拼接构建一个新元组。
python | Java | 注释 |
---|---|---|
tople | new | 创建元组 |
2.1.8.3 set(集合)
类似于Java中的set
2.1.8.3.1 集合运算
- &:交集
- |:并集
- ^:对称补集
- >:一个集合是否是另一个集合的超集
- <:一个集合是否是另一个集合的真子集
2.1.8.3.2 常用方法
方法 | 注释 |
---|---|
add() | 添加,如果已存在则不添加 |
clear() | 清空集合 |
copy() | 浅拷贝 |
difference(set) | 求补集 |
difference_update(set) | 求补集并替换原先的集合 |
discard(digit) | 从集合中移除一个数字,如果digit不是数字则不修改 |
intersection(set) | 求交集 |
intersection_update(set) | 求交集并替换原先的集合 |
issubset(set) | 判断当前集合是否是某集合的子集 |
pop() | 从集合中随机弹出一个元素 |
remove() | 从集合中删除元素e,不存在则报错 |
union(set) | 求并集 |
update(set) | 求并集并将结果赋值给原集合 |
2.1.8.3.3 集合推导式
l = [1, 2, 3, 4, 5]
s = {n for n in l}
s = {n for n in l if n > 2}
2.1.8.3.4 固定集合frozenset
不可变的set集合
f = frozenset([1, 2, 3])
2.1.9 dict(字典)
键值对,类似于Java中的map。
max()等函数是对键的操作。
2.1.9.1 创建、添加、修改、遍历
d = {}
d = dict()
d = {1: 1, 2: 3}
d['name'] = '张三' # d = {1: 1, 2: 3, 'name': '张三'}
d[1] = 2 # d = {1: 2, 2: 3, 'name': '张三'}
for k, v in d.items():
prient(k, ':', v)
2.1.9.2 常用方法
方法 | 注释 |
---|---|
clear() | 清空字典 |
pop(key) | 根据key删除字典中的键值对,并返回key对应的value |
copy() | 浅拷贝 |
update(dict) | 根据另一个字典对当前字典进行修改。当前字典没有的则拼接 |
get(key) | 根据key获取对应的value,与pop不同在于不会修改字典 |
keys() | 获取key |
values() | 获取valus |
items() | 获取item |
2.1.9.3 字典推导式
num = [1, 2, 3]
name = ['zs', 'ls', 'ww']
d = {num[i]: name[i] for i in range(len(num) if len(num) < len(name) else len(name))}
print(d) # {1: 'zs', 2: 'ls', 3: 'ww'}
d = {num[i]: name[i] for i in range(len(num) if len(num) < len(name) else len(name))}
print(d) # {2: 'ls', 3: 'ww'}
2.2 操作符
2.2.1 算术操作符
+、-、*、/、%、**、//
其中 / 结果为小数,// 结果为整数(相当于Java的 /);
** 为幂运算
2.2.2 比较操作符
<、<=、>、>=、==、!=
- is与is not:判断两个变量名是否绑定的同一个对象
- 区间判断
50 > x > 60
2.2.3 逻辑运算符
- and(相当于Java的 &&)
格式:表达式1 and 表达式2
当表达式1为False,则返回表达式1
当表达式1为True,则返回表达式2 - or(相当于Java的 ||)
格式:表达式1 or 表达式2
如果两个表达式都为false,返回表达式2;
如果两个表达式都为true,返回表达式1,
如果只有一个表达式为true,返回true的表达式 - not(相当于Java的 !)
取反,返回True或False
2.2.4 位运算符
&,|,^,<<,>>,~
与Java一样
2.2.5 操作符优先级
算术操作符 > 比较操作符 > 逻辑操作符
2.3 语句
2.3.1 分支语句
与Java类似。
其中(elif)相当于Java中的(else if)
2.3.1.1 三元操作符
if __name__ == '__main__':
x = 1
y = 2
result = x if x > y else y
print(result)
相当于Java中的:
public static void main(String[] args) {
int x = 1;
int y = 2;
int result = x > y ? x : y;
System.out.println(result);
}
2.3.2 循环语句
与Java不同:
- 后面可以跟else,即不满足循环条件之后的操作,可省略。
2.3.2.1 while循环
2.3.2.2 for循环
if __name__ == '__main__':
# range(3, 9, 2)函数获取一个从3开始,差值为2的,最大值小于9的等差数列
for i in range(3, 9, 2):
print(i)
相当于Java中的:
public static void main(String[] args) {
for (int i = 3; i < 9; i += 2) {
System.out.print(i);
}
}
2.3.2.2.1 range函数
range(3, 9, 2)函数获取一个从3开始,差值为2的,最大值小于9的等差数列。
range(3)函数获取一个从0开始,差值为1的,最大值小于3的等差数列,即默认从0开始,后面每个数在前面加一。
range(9, 3, -2)即递减
2.3.2.3 退出循环
break和continue,与Java中一样。
2.3.3 空语句
pass语句,占位,不做运算
2.4 关键字
- del:删除,释放空间
- def:定义函数
- global:声明全局变量,用在函数内
- self:类似于Java的this,指当前对象
- cls:类似于Java的this,指当前类
- raise:抛出异常,相当于Java中的 throw 。
2.5 注释
单行用井号#
多行用三对引号
2.6 函数
2.6.1 定义
通过 def 关键字定义函数
def 函数名(参数):
函数体
return 返回值
2.6.2 入参
- 默认参数:参数可以设置默认值,当调用时没有传参,就会使用默认值
def my_test(name = '张三', age):
print(name)
- 关键字参数:
调用函数时,可以指定参数传值,就不用按照顺序来
如果形参中有单个星号或可变参数,那么后面的参数必须是关键字参数
my_test(age = 8, name = '李四')
def my_test(name, *, age):
print(name, age)
if __name__ == '__main__':
my_test('李四', age=8)
- 元组参数(可变参数):
在参数前面加上一个星号 *
其实就是把传入的参数自动转为一个元组
def my_test(*param):
print(len(param))
print(param[0])
if __name__ == '__main__':
my_test(1, 2, 3)
- 字典参数(可变参数)
参数前加两个星号 **
即把传入的参数自动转为为一个字典
def add(**d):
print(len(d))
for k, v in d.items():
print(k, v)
if __name__ == '__main__':
add(a=1, b=2, c=3)
2.6.3 调用传参
- 字典传参
形参作为key,实参作为value,在传入的字典前面加上两个星号
def add(a, b, c):
print(a + b + c)
if __name__ == '__main__':
i = {'a': 1, 'b': 2, 'c': 3}
add(**i)
- 可变参数与不可变参数
其实就是Java中的值传递与引用传递
2.6.4 返回值
与Java不同,python函数一定有返回值(如果没有明确返回值,就会返回None对象),并且可以有多个返回值(其实就是自动打包为一个元组返回)。
8. 函数在同一个文件中,必须先定义,后调用(函数写在调用之前)
2.6.5 全局变量与局部变量
当函数内有与全局变量相同的变量时,默认是同名的局部变量。如果要操作全局变量,需要通过关键字 global 声明为全局变量
v = 100
def my_test():
global v
v = 200
print(v)
if __name__ == '__main__':
my_test()
print(v)
global声明的变量名不能是参数,也不能是已经声明的局部变量。
当函数内有嵌套函数时,如果使用nonlocal关键字,就是表明使外部函数的局部变量。多层嵌套时取最近的,
函数 | 注释 |
---|---|
globals() | 获取全局变量 |
locals() | 获取局部变量 |
2.6.6 嵌套函数
在函数中可以写函数。
2.6.7 高阶函数
函数可以作为入参传入另一个函数中。
函数也可以作为返回值,即返回一个函数。
2.6.7.1 内置高阶函数
- map
map(function, iterable)
map:映射
function:只有一个入参的函数
iterable:可迭代对象
即取出iterable中每个元素,作为function方法的入参,把function方法的返回结果替换iterable中取出的值,完成一个映射。如对iterable中每个元素求平方等。 - filter
reduce(function, iterable)
filter:过滤
function:只有一个入参的函数
iterable:可迭代对象
每次从iterable中取出一个元素,如果符合function函数的规则(function函数返回值为True),则放入一个新的iterable,最后返回新的iterable。 - reduce
reduce(function, iterable)
function:只有两个入参的函数
iterable:可迭代对象
每次从iterable中取出两个元素,按照函数function的规则运算后返回一个值,放入iterable,直到iterable中只有一个元素为止。如求和、最大值、最小值等。 - sorted
sorted(iterable, key=None, reverse=False)
sorted:排序
iterable:要排序的可迭代对象
key:根据哪个关键字排序。如key=abs(绝对值)、key=len(长度)、类的属性等
reverse:是否反转,默认False升序,True降序
2.6.8 lambda
if __name__ == '__main__':
my_add = lambda x, y: x + y
print(my_add(1, 2))
2.6.9 递归
与Java一样
2.6.10 生成器函数
2.6.10.1 生成序列型
- range
if __name__ == '__main__':
for i in range(1, 9, 2):
print(i)
- zip
可以将多个序列型数据,按照下标索引相同的放在一个元组里面,压缩为一个序列性数据。结果长度为入参中长度最小的。
if __name__ == '__main__':
num = [1, 2, 3, 4]
st = 'abc'
name = ["aa", 'ss', 'dd']
for n, s, na in zip(num, st, name):
print(n, s, na)
可以根据两个序列型数据来生成字典
if __name__ == '__main__':
num = [1, 2, 3, 4]
name = ["aa", 'ss', 'dd']
d = dict(zip(num, name))
for n, na in d.items():
print(n, na)
- 自定义生成器函数
带有 yield 语句的函数就是生成器函数,生成器和迭代器结合可以获得可迭代对象,可迭代对象可以通过 next() 函数获取到里面的每一个值,到最后会抛出 StopIteration 异常。也可以通过 for 循环取出里面的值。
def my_range(data):
step = 0
while step < data:
yield step
step += 1
if __name__ == '__main__':
it = iter(my_range(3))
print(next(it)) # 0
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # StopIteration
2.6.10.2 生成字典型
将一个可迭代对象按照从0(默认)或指定数值开始,生成一个数值作为key,可迭代对象中元素作为value的键值对数据。
if __name__ == '__main__':
l = ['a', 'b', 'c']
for s, n in enumerate(l, 100):
print(s, n)
三 模块与包
3.1 模块
模块就是一个.py文件
导入:
import 模块名 [as 模块简写]
from 模块名 import 属性/函数 [as 简写, ……]
3.2 包
每个包下面都有一个__init__.py文件,可以在里面导入该包的依赖。也是根据这个文件区分包与文件夹。
包的导入与模块一样。
四 类与对象
4.1 类
与Java的不同之处:
- 可以通过 类名.实例方法(实例) 调用实例方法,即通过类名调用实例方法,把实例作为入参
- 模块名不一定要与类名相同
- 实例变量要写在构造方里面,构造方法外面的是类变量
- 类变量类似于Java中的静态变量,但又不同。
Java中类与实例访问的都是同一个,相互影响。
python中,如果一个实例修改了类变量,实际是创建了一个独属于当前实例的类变量,不会影响原来的类变量,也不会受原先的类变量或其他实例的类变量影响,不过如果实例对象没有修改类变量,就会和其他实例对象和类使用同一个类变量 - isinstance(obj, class或class的元组):判断对象是否是某个类型,类似于Java中的 instanceof 。不过 isinstance 函数可以一次判断对象是否属于哪些类型
4.1.1 预置属性
- _class_:类型
- _dict_:实例的字典形式
- _doc_:类的注释
- _module_:模块名
- _slots_:锁定类的属性,这种方式定义的类的属性无法增加或减少
4.1.2 属性
- 实例属性
写在构造函数里面的属性,只属于实例对象。 - 类属性
类似于Java中的静态属性,但又不同。
Java中类与实例访问的都是同一个,相互影响。
python中,如果一个实例修改了类属性,实际是创建了一个独属于当前实例对象的同名属性,不会影响原来的类属性(类属于函数内操作全局变量),也不会受原先的类属性或其他实例对象的类属性影响,不过如果实例对象没有修改类属性,就会和其他实例对象和类使用同一个类属性,通过类修改类属性之后,所有实例对象都会受影响。 - 特殊属性
@property:把函数转为属性。即相当于创建了一个与函数名相同的属性,把函数的结果赋值给它。
下面示例相当于定义了半径 radius 与面积 area 两个属性,并且这两个属性相互绑定,如果其中一个被改变,另一个也会跟着改变。
import math
class Circle:
"""
圆类
"""
def __init__(self, r):
self.radius = r
@property
def area(self):
print('area 函数被调用,半径为:' + str(self.radius))
return math.pi * self.radius ** 2
@area.setter
def area(self, a):
self.radius = math.sqrt(a / math.pi)
print('半径改变')
if __name__ == '__main__':
c1 = Circle(10)
print(c1.area)
c1.area = 314.1592653
print(c1.radius)
- 属性管理函数
函数 | 注释 |
---|---|
getattr(obj, name[, default]) | 获取对象某个属性的值相当于obj.name |
hasattr(obj, name) | 判断对象是否有某个属性 |
setattr(obj, name, value) | 给对象某个属性设置值,可以给不存在的属性赋值,即给类新增一个属性 |
delattr(obj, name) | 删除对象某个属性 |
4.1.3 方法
- 构造方法
与Java不同,通过 def init 创建。
没有无惨构造函数。 - 实例方法
类似于Java的普通方法。
第一个入参为 self ,代表当前对象 - 类方法
在方法上加 @classmethod ,第一个入参为 cls ,代表当前类。主要用于操作类属性 - 静态方法
类似于Java的静态方法。但不能访问类属性与实例属性
在方法上加 @staticmethod ,入参不用传 self 或 cls 。
4.1.4 运算符重载
python中重载的含义与Java一样。
每个类都有一些默认的内置方法,其中每个运算符都有一个对应的内置方法。而通过重载这个对应的内置方法,就可以通过运算符操作这个类。如 + 对应的内置方法为 _add_(self, other)。
反向算术运算符:如 _radd_(self, other) 等价于 other - self
4.1.5 抽象类
含义与Java一样。
from abc import ABC, abstractmethod
class Base(ABC):
def __init__(self):
pass
@abstractmethod
def get(self):
print("Base.get")
pass
if __name__ == '__main__':
b = Base()
python中的抽象方法可以有方法体。
4.2 三大特征
4.2.1 封装
python中只有公共和私有两种。
通过对属性和方法的命名来规定是否私有。
如果以双下划线 __ 开头,不以双下划线结尾的属性和方法,就是私有的属性和方法。相当于Java中被 private 修饰的属性和方法。
其他的都是公共的属性和方法,相当于Java中被 public 修改时的属性和方法。
4.2.2 继承
class 类名 (超类名1, 超类名, ……):
pass:
函数 | 注释 |
---|---|
super | 根据子类获取父类的对象 |
issubclass(x, A_tuple) | 判断一个类是否是某个类或某些类中其中一个的基类 |
python支持多继承。
对于多继承中同名属性和方法,执行广度优先,即从继承列表第一个开始找,找到一个就停止搜索。
4.2.3 多态
多态、重写与Java一样
五 异常
5.1 断言
与Java类似
assert i > 0, 'i不能小于0'
5.2 捕获、处理异常
if __name__ == '__main__':
x, y = 10, 1
try:
z = x / y
except ValueError as err:
print('发生值错误异常', err)
except ZeroDivisionError as err:
print('发生除数为零异常', err)
except:
print("发生未知异常")
else:
print("没有发生异常")
finally:
print('最终语句')
5.3 抛出异常
raise ValueError
raise ValueError('不允许的数据')
5.4 with语句
自动管理环境,把资源释放与 finally 分开。
下面代码当发生异常时,会自动关闭流。
if __name__ == '__main__':
with open('myfile.txt', 'r') as f:
while True:
l = f.readline()
if len(l) > 0:
print(l)
else:
f.close()
with与环境管理器一起使用,而环境管理器是实现了 _enter_ 函数与 _exit_ 函数的类。with通过 _enter_ 方法初始化,然后在 _exit_ 中做善后以及处理异常。