Python 汇总
- 基础语法
- 基本数据类型
- 类型装换
- 推导式
- 解释器
- 注释
- 运算符
- 数字
- 字符串
- 访问字符串中的值
- 转义字符
- 字符串运算符
- 字符串格式化
- 字符串输入
- 下标和切片
- Unicode 字符串
- 字符串内建函数
- find 检测 str 是否包含在 str 中
- index 检测 str 是否包含在 str 中
- count 在 string 里面出现的次数
- replace 把 mystr 中的 str1 替换成 str2
- split 以 str 为分隔符切片 mystr
- join 将 mystr 插入到 str 中每个元素之间
- capitalize 将字符串的第一个字符转换为大写
- title 把字符串的每个单词首字母大写
- startswith 检查字符串是否是以 str 开头
- endswith 检查字符串是否以 obj 结束
- lower 转换 str 中所有大写字符为小写
- upper 转换 str 中的小写字母为大写
- 统计字符串出现的次数
- 列表
- 元组
- Set(集合)
- 字典
- 判断
- 循环
- 函数
- 变量
- 文件操作
- 面对对象
- 继承
- 异常
- 模块
- 编码规范
- Python 自动化
计划 | 上午 | 下午 |
---|---|---|
2.25 | 环境搭建 | 基础语法 , 基础数据类型 |
2.28 | 类型转换 , 推导式 | 解释器 , 注释 , 运算符 |
3.1 | 数字 , 字符串 | 列表 , 元组 |
3.2 | 字典 , 集合 | 条件控制 , 循环 , 迭代 |
3.3 | 函数 , 数据结构 | 模块 , IO , File |
3.4 | OS , 错误异常 , 面对对象 | 命名空间 , 标准库 , 总结 |
基础语法
编码
Python 3 源码文件以 UTF-8
编码,所有字符串都是 unicode
字符串
标识符
- 第一个字符必须是字母表中 字母 或 下划线
_
- 标识符的其他的部分由字母、数字和下划线组成
- 标识符对大小写敏感
Python 3 中,可用中文作为变量名,非 ASCII 标识符
python保留字
保留字 ( 关键字 ) ,不能将它们用作任何标识符名称。Python 的标准库提供 keyword
模块,可以输出当前版本的所有关键字
"""
@dauthor : ${USER}
@date : ${DATE} ${TIME}
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
import keyword
print(keyword.kwlist)
注释
Python 中单行注释以 #
开头
"""
@dauthor : ${USER}
@date : ${DATE} ${TIME}
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
# 第一个注释
print("hello cpuCode") # 第二个注释
多行注释可以用多个 #
号,还有 '''
和 """
行与缩进
python 使用缩进来表示代码块,不使用大括号 {}
缩进的空格数是可变,但同一个代码块的语句必须相同的缩进空格数
"""
@dauthor : cpucode
@date : 2022/2/25 14:01
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
# 行与缩进
if True:
print ("True")
else:
print ("False")
多行语句
Python 一般一行写完一条语句,但如果语句很长,我们可以使用反斜杠 \
来实现多行语句
在 []
, {}
, 或 ()
中的多行语句,不需要使用反斜杠 \
"""
@dauthor : cpucode
@date : 2022/2/25 14:52
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
item_one = 'cpu '
item_two = 'code '
item_three = 'cpuCode '
total = item_one + \
item_two + \
item_three
total2 = ['item_one', 'item_two', 'item_three',
'item_four', 'item_five']
print(total)
print(total2)
数字(Number)类型
Python 中数字有四种类型:
- 整数
- 布尔型
- 浮点数
- 复数
int (整数) : 如 1, 只有一种整数类型 int,表示为长整型,没有 python2 中的 Long
bool (布尔) : 如 True
float (浮点数) : 如 1.23、3E-2
complex (复数) : 如 1 + 2j
、 1.1 + 2.2j
字符串(String)
- Python 中单引号
'
和双引号"
使用完全相同 - 使用三引号 (
'''
或"""
) 可以指定一个多行字符串 - 转义符
\
- 反斜杠可以用来转义,使用
r
可以让反斜杠不发生转义。 如r"this is a line with \n"
则\n
会显示,并不是换行 - 按字面意义级联字符串,如
"this " "is " "string"
会被自动转换为this is string
- 字符串可以用
+
运算符连接在一起,用*
运算符重复 - Python 中的字符串有两种索引方式,从左往右以
0
开始,从右往左以-1
开始 - Python 中的字符串不能改变
- Python 没有单独的字符类型,一个字符就是长度为 1 的字符串
- 字符串的截取的语法格式 , 如:变量[头下标:尾下标:步长]
"""
@dauthor : cpucode
@date : 2022/2/25 14:35
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
str = '123456789'
print(str) # 输出字符串
print(str[0:-1]) # 输出第一个到倒数第二个的所有字符
print(str[0]) # 输出字符串第一个字符
print(str[2:5]) # 输出从第三个开始到第五个的字符
print(str[2:]) # 输出从第三个开始后的所有字符
print(str[1:5:2]) # 输出从第二个开始到第五个且每隔一个的字符(步长为2)
print(str * 2) # 输出字符串两次
print(str + '你好') # 连接字符串
print('------------------------------')
# 使用反斜杠(\)+n转义特殊字符
print('hello\ncpuCode')
# 在字符串前面添加一个 r,表示原始字符串,不会发生转义
print(r'hello\ncpuCode')
r 指 raw,即 raw string
,会自动将反斜杠转义
print('\n')
print(r'\n')
空行
函数之间或类的方法之间用空行分隔,表示一段新的代码的开始
类和函数入口之间也用一行空行分隔,以突出函数入口的开始
空行与代码缩进不同,空行并不是 Python 语法的一部分。书写时不插入空行,Python 解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构
等待用户输入
按回车键后就会等待用户输入
"""
@dauthor : cpucode
@date : 2022/2/25 15:02
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
input("\n\n按下 enter 键后退出 ")
\n\n
在结果输出前会输出两个新的空行。一旦用户按下 enter 键时,程序将退出
同一行显示多条语句
Python 可以在同一行中使用多条语句,语句之间使用分号 ;
分割
"""
@dauthor : cpucode
@date : 2022/2/25 15:04
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
import sys; x = 'cpuCode'; sys.stdout.write(x + '\n')
多个语句构成代码组
缩进相同的一组语句构成一个代码块 ( 代码组 )
像 if
、while
、def
和 class
这样的复合语句,首行以关键字开始,以冒号( : )结束,该行后的一行或多行代码构成代码组
我们将首行及后面的代码组称为一个子句 ( clause )
if expression :
suite
elif expression :
suite
else :
suite
print 输出
print 默认输出是换行,如果实现不换行需要在变量末尾加上 end = ""
"""
@dauthor : cpucode
@date : 2022/2/25 15:06
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
x = "a"
y = "b"
# 换行输出
print(x)
print(y)
print('---------')
# 不换行输出
print(x, end=" ")
print(y, end=" ")
print()
import 与 from…import
- 在 python 用
import
或者from...import
来导入相应的模块 - 将整个模块( somemodule ) 导入,如 :
import somemodule
- 从某个模块中导入某个函数 , 如 :
from somemodule import somefunction
- 从某个模块中导入多个函数 , 如 :
from somemodule import firstfunc, secondfunc, thirdfunc
- 将某个模块中的全部函数导入,如 :
from somemodule import *
"""
@dauthor : cpucode
@date : 2022/2/25 15:19
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
import sys
print('================ Python import mode ==========================')
print('命令行参数为:')
for i in sys.argv:
print(i)
print('\n python 路径 : ', sys.path)
"""
@dauthor : cpucode
@date : 2022/2/25 15:22
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
# 导入特定的成员
from sys import argv, path
print('=======python from import=================')
# 因为已经导入path成员,所以此处引用时不需要加 sys.path
print('path : ', path)
命令行参数
python -h
基本数据类型
Python3 中有六个标准的数据类型:
- Number(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- Dictionary(字典)
Python3 的六个标准数据类型中:
不可变数据 :Number(数字)、String(字符串)、Tuple(元组)
可变数据:List(列表)、Dictionary(字典)、Set(集合)
- Python 中的变量不需要声明
- 每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建
- 在 Python 中,变量就是变量,它没有类型,“类型” 是变量所指的内存中对象的类型
- 等号(=)用来给变量赋值
- 等号(=)运算符左边是一个变量名 , 等号(=)运算符右边是存储在变量中的值
"""
@dauthor : cpucode
@date : 2022/2/25 16:03
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
counter = 100 # 整型变量
miles = 1000.0 # 浮点型变量
name = "cpuCode" # 字符串
print(counter)
print(miles)
print(name)
多个变量赋值
Python 允许你同时为多个变量赋值 , 也可以为多个对象指定多个变量
"""
@dauthor : cpucode
@date : 2022/2/25 16:23
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = b = c = 1
d, e, f = 1, 2, "cpuCode"
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
Number(数字)
Python3 支持
- int
- float
- bool
- complex(复数)
在 Python 3 里,只有一种整数类型 int
,表示为长整型,没有 python2 中的 Long
内置的 type()
函数可以用来查询变量所指的对象类型
isinstance 和 type 的区别在于:
- type() 不会认为子类是一种父类类型
- isinstance() 会认为子类是一种父类类型
"""
@dauthor : cpucode
@date : 2022/2/25 16:45
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
class A:
pass
class B(A):
pass
a, b, c, d = 20, 5.5, True, 4+3j
d = 111
print(type(a), type(b))
print(type(c), type(d))
print(isinstance(d, int))
print("/****************************************/")
print("isinstance(A(), A) : ", isinstance(A(), A))
print("type(A()) == A : ", type(A()) == A)
print("isinstance(B(), A) : ", isinstance(B(), A))
print("type(B()) == A : ", type(B()) == A)
Python3 中,bool 是 int 的子类
True 和 False 可以和数字相加, True1、False0 会返回 True,
is 来判断类型
在 Python2 中是没有布尔型的
数字 0 表示 False,用 1 表示 True
"""
@dauthor : cpucode
@date : 2022/2/28 9:07
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
print("isinstance(bool, int) : ", isinstance(bool, int))
print("True == 1 : ", True == 1)
print("False == 0 : ", False == 0)
print("True + 1 : ", True + 1)
print("False + 1 : ", False + 1)
print("1 is True : ", (1 is True))
print("0 is False : ", (0 is False))
数值运算
-
Python 可以同时为多个变量赋值,如
a, b = 1, 2
-
一个变量可以通过赋值指向不同类型的对象
-
数值的除法包含两个运算符:
/
返回一个浮点数,//
返回一个整数 -
在混合计算时,Python 把整型转换为浮点数
-
Python 支持复数,复数由实数部分和虚数部分构成,可以用
a + bj
, 或complex(a,b)
表示, 复数的 实部a 和 虚部b 都是浮点型
"""
@dauthor : cpucode
@date : 2022/2/28 9:13
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
# 加法
print("1 + 1 = ", 1 + 1)
# 减法
print("5.5 - 1 = ", 5.5 - 1)
# 乘法
print("2 * 8 = ", 2 * 8)
# 除法,得到一个浮点数
print("3 / 6 = ", 3 / 6)
# 除法,得到一个整数
print("3 // 6 = ", 3 // 6)
# 取余
print("18 % 5 = ", 18 % 5)
# 乘方
print("5 ** 2 = ", 5 ** 2)
String(字符串)
Python 中的字符串用单引号 '
或双引号 "
括起来,同时使用反斜杠 \
转义特殊字符
变量[头下标:尾下标]
索引值以 0
为开始值,-1
为从末尾的开始位置
加号
+
是字符串的连接符
星号*
表示复制当前字符串,与之结合的数字为复制的次数
"""
@dauthor : cpucode
@date : 2022/2/28 9:39
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
str = 'cpuCode'
# 输出字符串
print("str : ", str)
# 输出第一个到倒数第二个的所有字符
print("str[0:-1] : ", str[0:-1])
# 输出字符串第一个字符
print("str[0] : ", str[0])
# 输出从第三个开始到第五个的字符
print("str[3:6] : ", str[3:6])
# 输出从第三个开始的后的所有字符
print("str[3:] : ", str[3:])
# 输出字符串两次,也可以写成 print (2 * str)
print("str * 2 : ", str * 2)
# 连接字符串
print("str + \"_Test\" : ", str + "_Test")
Python 使用反斜杠 \
转义特殊字符,如不让反斜杠发生转义,可在字符串前面添加一个 r
,表示原始字符串
"""
@dauthor : cpucode
@date : 2022/2/28 9:46
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
print('cpu\nCode')
print(r'cpu\nCode')
反斜杠( \
) 可以作为续行符,表示下一行是上一行的延续。也可使用 """..."""
或者 '''...'''
跨越多行
Python 没有单独的字符类型,一个字符就是长度为 1 的字符串
与 C 字符串不同的是,Python 字符串不能被改变
向一个索引位置赋值,如 :word[0] = 'C
会导致错误
"""
@dauthor : cpucode
@date : 2022/2/28 9:48
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
word = 'cpuCode'
print(word[0], word[3])
print(word[-1], word[-4])
- 反斜杠可以用来转义,使用
r
可以让反斜杠不发生转义 - 字符串可以用
+
运算符连接在一起,用*
运算符重复 - Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始
- Python 中的字符串不能改变
详细
- 字符串使用单引号、双引号或三引号表示,三者意义相同,并没有区别
- 字符串是不可变
- (2.5+)字符串的拼接高效
- 字符串的格式化(string.format)常用在输出、日志的记录
字符串是由独立字符组成的一个序列,在单引号(''
)双引号( ""
)或 三引号之中(''' '''
或 """ """
)
s1 = 'cpu'
s2 = "cpu"
s3 = """cpu"""
s1 == s2 == s3
Python 支持转义字符
转义字符 | 说明 |
---|---|
\newline | 接下一行 |
\ | \ |
’ | ’ |
" | " |
\n | 换行 |
\t | 横向制表符 |
\b | 退格 |
\v | 纵向制表符 |
s = 'a\nb\tc'
print(s)
path = 'hive://ads/training_table'
# 返回'ads'
namespace = path.split('//')[1].split('/')[0]
# 返回 'training_table'
table = path.split('//')[1].split('/')[1]
data = query_data(namespace, table)
- string.strip(str) : 去掉首尾的 str 字符串
- string.lstrip(str) : 只去掉开头的 str 字符串
- string.rstrip(str) : 只去掉尾部的 str 字符串
字符串的格式化
print('id: {}, name: {}'.format(id, name))
Python 之前版本 :
print('id: %s, name: %s' % (id, name))
- %s : 字符串型
- %d : 整型
List(列表)
List(列表) 是 Python 中使用最频繁的数据类型
列表中元素的类型可以不相同,支持数字,字符串 , 列表(所谓嵌套)
列表是写在方括号 []
之间、用逗号分隔开的元素列表
和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表
列表截取的语法格式 :
变量[头下标:尾下标]
索引值以 0
为开始值,-1
为从末尾的开始位置
- 加号
+
: 列表连接运算符 - 星号
*
: 重复操作
"""
@dauthor : cpucode
@date : 2022/2/28 10:02
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
list = ['abc', 222, 3.3, 'cpuCode', 10.1]
tinylist = [111, 'cpu']
a = [1, 2, 3, 4, 5, 6]
# 输出完整列表
print("list : ", list)
# 输出列表第一个元素
print("list[0] : ", list[0])
# 从第二个开始输出到第三个元素
print("list[1:3] : ", list[1:3])
# 输出从第三个元素开始的所有元素
print("list[2:] : ", list[2:])
# 输出两次列表
print("tinylist * 2 : ", tinylist * 2)
# 连接列表
print("list + tinylist : ", list + tinylist)
print("/*************************************/")
print("a = ", a)
print("a[0] : ", a[0])
print("a[0] : ", a[2:5])
# 将对应的元素值设置为 []
a[2:5] = []
print("a = ", a)
- List 写在方括号之间,元素用逗号隔开
- 和字符串一样,list 可以被索引和切片
- List 可以使用
+
操作符进行拼接 - List 中的元素是可以改变的
Python 列表截取可以接收第三个参数,参数作用是截取的步长,以下实例在索引 1 到索引 4 的位置并设置为步长为 2(间隔一个位置)来截取字符串
第三个参数为负数表示逆向读取
"""
@dauthor : cpucode
@date : 2022/2/28 10:14
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
def reverseWords(input):
# 通过空格将字符串分隔符,把各个单词分隔为列表
inputWords = input.split(" ")
# 翻转字符串
# 假设列表 list = [1,2,3,4],
# list[0]=1, list[1]=2 ,而 -1 表示最后一个元素 list[-1]=4 ( 与 list[3]=4 一样)
# inputWords[-1::-1] 有三个参数
# 第一个参数 -1 表示最后一个元素
# 第二个参数为空,表示移动到列表末尾
# 第三个参数为步长,-1 表示逆向
inputWords = inputWords[-1::-1]
output = ' '.join(inputWords)
# 重新组合字符串
return output
if __name__ == '__main__':
input = 'I like cpuCode'
rw = reverseWords(input)
print(rw)
Tuple(元组)
元组(tuple)与列表类似,不同是元组的元素不能修改
元组写在小括号 ()
里,元素之间用逗号隔开
元组与字符串类似,可以被索引且下标索引从 0 开始,-1 为从末尾开始的位置。也可以进行截取
"""
@dauthor : cpucode
@date : 2022/2/28 10:27
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
tuple = ('abcd', 8848, 2.21, 'cpuCode', 48.2)
tinytuple = (123, 'cpu')
# 输出完整元组
print(tuple)
# 输出元组的第一个元素
print(tuple[0])
# 输出从第二个元素开始到第三个元素
print(tuple[1:3])
# 输出从第三个元素开始的所有元素
print(tuple[2:])
# 输出两次元组
print(tinytuple * 2)
# 连接元组
print(tuple + tinytuple)
# 修改元组元素的操作是非法的
tuple[1] = 11
string、list 和 tuple 都属于 sequence(序列)
与字符串一样,元组的元素不能修改
元组也可以被索引和切片,方法一样
注意构造包含 0 或 1 个元素的元组的特殊语法规则
元组也可以使用+
操作符进行拼接
List & Tuple 区别
列表(list)和元组(tuple),都是一个可以放置任意数据类型的有序集合
- 列表是动态,长度大小不固定,可以随意地增加、删减或者改变元素(mutable), 列表的存储空间略大于元组,性能略逊于元组
- 元组是静态,长度大小固定,无法增加删减或者改变(immutable) , 元组相对于列表更加轻量级,性能稍优
列表和元组都支持负数索引
# 列表
l = [1, 2, 3, 4]
l[-1]
# 元组
tup = (1, 2, 3, 4)
tup[-1]
列表和元组都支持切片操作
l = [1, 2, 3, 4]
# 返回列表中索引从 1 到 2 的子列表
l[1:3]
tup = (1, 2, 3, 4)
# 返回元组中索引从 1 到 2 的子元组
tup[1:3]
列表和元组都可以随意嵌套
# 列表的每一个元素也是一个列表
l = [[1, 2, 3], [4, 5]]
# 元组的每一个元素也是一元组
tup = ((1, 2, 3), (4, 5, 6))
通过 list()
和 tuple()
函数相互转换
l = list((1, 2, 3))
tup = tuple([1, 2, 3])
l.count(3)
l.index(4)
l.reverse()
l.sort()
tup.count(3)
tup.index(7)
list(reversed(tup))
sorted(tup)
- count(item) : 统计列表 / 元组中 item 出现的次数
- index(item) : 返回列表 / 元组中 item 第一次出现的索引
- list.reverse() 和 list.sort() : 分别原地倒转列表和排序(元组没有内置的这两个函数)
- reversed() 和 sorted() : 对列表 / 元组进行倒转和排序,但是会返回一个倒转后或 排好序的新的列表 / 元组
列表和元组存储差异
l = [1, 2, 3]
l.__sizeof__()
tup = (1, 2, 3)
tup.__sizeof__()
元组的存储空间要比列表少 16 字节
列表是动态的,所以需要存储指针,来指向对应的元素 , 列表可变,所以需要额外存储分配的长度大小(8 字节), 为了实时追踪列表空间的使用情况,当空间不足时,及时分配额外空间
l = []
# 空列表的存储空间为 40 字节
l.__sizeof__()
# 加入元素1 后,列表会分配存储 4 个元素的空间
l.append(1)
l.__sizeof__()
l.append(3)
l.append(4)
l.__sizeof__()
# // 加元素 5 后,列表的空间不足,会额外分配存储 4 个元素的空间
l.append(5)
l.__sizeof__()
列表空间分配的过程 : 为了减小每次增加 / 删减操作时空间分配的开销,每次分配空间时都会额外多分配一些,这样的机制(over-allocating)保证操作的高效性:增加 / 删除的时间复杂度均为 O(1)
元组长度大小固定,元素不可变,所以存储空间固定
列表和元组的性能
元组比列表更加轻量级些,所以总体上,元组的性能速度要略优于列表
静态变量( 元组 ),如果不被使用且占用空间不大时,垃圾回收机制不会回收 , 下次直接使用
计算初始化一个相同元素的列表和元组分别所需的时间
python3 -m timeit 'x=(1,2,3,4,5,6,7,8,9)'
python3 -m timeit 'x=[1,2,3,4,5,6,7,8,9]
数据量大就可以看出差距
想要增加、删减或 改变元素,那么列表显然更优
- 存储的数据和数量不变,直接传给前端渲染,选用元组更合适
- 存储的数据或数量是可变的,用列表更合适
Set(集合)
集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员
使用大括号 { }
或者 set()
函数创建集合
创建一个空集合必须用
set()
而不是{ }
,因为{ }
是用来创建一个空字典
"""
@dauthor : cpucode
@date : 2022/2/28 10:53
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
sites = {'cpu', 'code', 'cpuCode', 'baobei'}
# 输出集合,重复的元素被自动去掉
print("sites = ", sites)
# 成员测试
if 'cpuCode' in sites:
print('cpuCode 在集合中')
else:
print('cpuCode 不在集合中')
# set可以进行集合运算
a = set('abc')
b = set('abb')
print("a = ", a)
print("b = ", b)
# a 和 b 的差集
print("a - b = ", a - b)
# a 和 b 的并集
print("a | b = ", a | b)
# a 和 b 的交集
print("a & b = ", a & b)
# a 和 b 中不同时存在的元素
print("a ^ b = ", a ^ b)
Dictionary(字典)
字典(dictionary)是 Python中内置数据类型
列表是有序的对象集合,字典是无序的对象集合
两者区别:字典当中的元素是通过键来存取的,而不是通过偏移存取
字典是一种映射类型,字典用 { }
标识,它是一个无序的 键(key) : 值(value) 的集合
键 (key) 必须使用不可变类型
在同一个字典中,键(key) 必须是唯一
"""
@dauthor : cpucode
@date : 2022/2/28 11:09
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
dictnum = {}
dictnum['one'] = '1 - cpu'
dictnum[2] = '2 - code'
tinydict = {'name': 'cpuCode', 'code': 1, 'site': 'https://blog.csdn.net/qq_44226094'}
# 输出键为 'one' 的值
print("dict['one'] : ", dictnum['one'])
# 输出键为 2 的值
print("dict[2] : ", dictnum[2])
# 输出完整的字典
print("tinydict : ", tinydict)
# 输出所有键
print("tinydict.keys() : ", tinydict.keys())
# 输出所有值
print("tinydict.values() : ", tinydict.values())
print("/*****************************************************************/")
dictValue = dict([('cpuCode', 1), ('cpu', 2), ('code', 3)])
print("dictValue : ", dictValue)
dictValue1 = {x: x**2 for x in (2, 4, 6)}
print("dictValue1 : ", dictValue1)
dictValue2 = dict(cpuCode=1, cpu=2, code=3)
print("dictValue2 : ", dictValue2)
构造函数 dict()
可以直接从键值对序列中构建字典
{x: x**2 for x in (2, 4, 6)}
使用是字典推导式
字典是一种映射类型,它的元素是键值对
字典的关键字必须为不可变类型,且不能重复
创建空字典使用{ }
字典 & 集合 区别
- 字典 : 由键(key)和值(value)配对组成的元素的集合 , 在 Python3.7+ 是有序的数据结构
- 集合 : 无序 , 唯一 ,其内部的哈希表存储结构,保证了查找、插入、删除操作的高效性
性能
- 字典 : 存储了哈希值(hash)、键和值 3 个元素
- 集合 : 哈希表内没有键和值的配对,只有单一的元素
哈希表除了字典本身的结构,把索引 和 哈希值、键、值单独分开
Indices
----------------------------------------------------
None | index | None | None | index | None | index ...
----------------------------------------------------
Entries
--------------------
hash0 key0 value0
---------------------
hash1 key1 value1
---------------------
hash2 key2 value2
---------------------
...
---------------------
类型装换
对数据内置的类型进行转换,数据类型的转换,只需要将数据类型作为函数名
Python 数据类型转换分为两种:
- 隐式类型转换 - 自动完成
- 显式类型转换 - 需要使用类型函数来转换
隐式类型转换
在隐式类型转换中,Python 会自动将一种数据类型转换为另一种数据类型,不需要干预
对两种不同类型的数据进行运算,较低数据类型(整数)就会转换为较高数据类型(浮点数)以避免数据丢失
"""
@dauthor : cpucode
@date : 2022/2/28 13:50
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
num_int = 123
num_flo = 1.23
# 不同数据类型的变量 num_int 和 num_flo 相加,并存储在变量 num_new 中
num_enw = num_int + num_flo
# 查看三个变量的数据类型
print("type(num_int) : ", type(num_int))
print("type(num_flo) : ", type(num_flo))
print("type(num_new) : ", type(num_enw))
# 将较小的数据类型转换为较大的数据类型,以避免数据丢失
print("num_new : ", num_enw)
print("/**************************************/")
num_str = "456"
print("type(num_str) : ", type(num_str))
# 整型和字符串类型运算结果会报错,输出 TypeError
print("num_int + num_str : ", num_int + num_str)
显式类型转换
在显式类型转换中,用户将对象的数据类型转换为所需的数据类型
使用 int()
、float()
、str()
等预定义函数来执行显式类型转换
"""
@dauthor : cpucode
@date : 2022/2/28 13:54
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
# int() 强制转换为整型
# x 输出结果为 1
x = int(1)
# y 输出结果为 2
y = int(2.8)
# z 输出结果为 3
z = int("3")
print(x)
print(y)
print(z)
print("/**********************************************/")
# float() 强制转换为浮点型
# x 输出结果为 1.0
a = float(1)
# y 输出结果为 2.8
b = float(2.8)
# z 输出结果为 3.0
c = float("3")
# w 输出结果为 4.2
d = float("4.2")
print(a)
print(b)
print(c)
print(d)
print("/**********************************************/")
# str() 强制转换为字符串类型
# e 输出结果为 's1'
e = str("s1")
# g 输出结果为 '2'g
f = str(2)
# g 输出结果为 '3.0'
g = str(3.0)
print(e)
print(f)
print(g)
print("/**********************************************/")
# 整型和字符串类型进行运算,用强制类型转换
num_int = 123
num_str = "456"
print("num_int : ", num_int)
print("num_str : ", num_str)
print("type(num_int) : ", type(num_int))
print("type(num_str) : ", type(num_str))
# 强制转换为整型
num_str = int(num_str)
print("类型转换后,num_str : ", num_str)
print("类型转换后,type(num_str) : ", type(num_str))
num_sum = num_int + num_str
print("num_sum : ", num_sum)
print("type(num_sum) : ", type(num_sum))
计算 a + aa + aaa + aaaa 的值
def calculate_sum(int_1: int) -> None:
# a + aa + aaa + aaaa
str_1 = str(int_1)
str_2 = str_1 * 2
str_3 = str_1 * 3
str_4 = str_1 * 4
print(int_1 + int(str_2) + int(str_3) + int(str_4))
推导式
Python 推导式是一种独特的数据处理方式,将一个数据序列构建另一个新的数据序列的结构体
Python 支持各种数据结构的推导式:
- 列表 ( list ) 推导式
- 字典 ( dict ) 推导式
- 集合 ( set ) 推导式
- 元组 ( tuple ) 推导式
列表推导式
[表达式 for 变量 in 列表]
[out_exp_res for out_exp in input_list]
[表达式 for 变量 in 列表 if 条件]
[out_exp_res for out_exp in input_list if condition]
- out_exp_res:列表生成元素表达式,可以是有返回值的函数
- for out_exp in input_list:迭代 input_list 将 out_exp 传入到 out_exp_res 表达式中
- if condition:条件语句,可以过滤列表中不符合条件的值
"""
@dauthor : cpucode
@date : 2022/2/28 14:14
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
names = ['cpu', 'code', 'cpuCode']
new_names = [name.upper() for name in names if len(name) > 3]
print(new_names)
multiples = [i for i in range(10) if i % 3 == 0]
print(multiples)
字典推导式
{ key_expr: value_expr for value in collection }
{ key_expr: value_expr for value in collection if condition }
"""
@dauthor : cpucode
@date : 2022/2/28 14:18
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
listdemo = ['cpu', 'code', 'cpuCode']
# 将列表中各字符串值为键,各字符串的长度为值,组成键值对
newdict = {key:len(key) for key in listdemo}
print(newdict)
# 以三个数字为键,三个数字的平方为值
dic = {x: x**2 for x in (2, 4, 6)}
print(dic)
print("type(dic) : ", type(dic))
集合推导式
{ expression for item in Sequence }
{ expression for item in Sequence if conditional }
"""
@dauthor : cpucode
@date : 2022/2/28 14:18
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
setnew = {i**2 for i in (1, 2, 3)}
print(setnew)
a = {x for x in 'cpuCode' if x not in 'cpu'}
print(a)
print("type(a) : ", type(a))
元组推导式
元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组
元组推导式和列表推导式的用法也完全相同,只是元组推导式是用 ()
圆括号将各部分括起来,而列表推导式用的是中括号 []
,另外元组推导式返回的结果是一个生成器对象
"""
@dauthor : cpucode
@date : 2022/2/28 14:18
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = (x for x in range(1, 10))
# 返回的是生成器对象
print(a)
# 使用 tuple() 函数,可以直接将生成器对象转换成元组
print("tuple(a) : ", tuple(a))
解释器
Linux/Unix 的系统上,一般默认的 python 版本为 2.x,将 python3.x 安装在 /usr/local/python3
目录中
安装完成后,我们可以将路径 /usr/local/python3/bin
添加到您的 Linux/Unix 操作系统的环境变量中,就可以 shell 终端输入下面的命令来启动 Python3
PATH=$PATH:/usr/local/python3/bin/python3
交互式编程
脚本式编程
test.py
文件中
#! /usr/bin/env python3
print ("Hello, cpuCode!");
修改脚本权限,使其有执行权限
chmod 777 test.py
注释
确保对模块, 函数, 方法和行内注释使用正确的风格
Python 中的注释
- 单行注释
- 多行注释
Python 中单行注释以 #
开头
# 这是一个注释
print("Hello, cpuCode!")
多行注释用三个单引号 '''
或者三个双引号 """
将注释括起来
单引号('''
)
#!/usr/bin/python3
'''
这是多行注释,用三个单引号
这是多行注释,用三个单引号
这是多行注释,用三个单引号
'''
print("Hello, cpuCode!")
双引号("""
)
#!/usr/bin/python3
"""
这是多行注释,用三个双引号
这是多行注释,用三个双引号
这是多行注释,用三个双引号
"""
print("Hello, cpuCode!")
运算符
Python 语言支持类型的运算符 :
- 算术运算符
- 比较(关系)运算符
- 赋值运算符
- 逻辑运算符
- 位运算符
- 成员运算符
- 身份运算符
- 运算符优先级
算术运算符
运算符 | 功能 | 描述 |
---|---|---|
+ | 加 | 和 |
- | 减 | 差 |
* | 乘 | 积 |
/ | 除 | 商 |
% | 取模 | 余数 |
** | 幂 | 次方 |
// | 取整除 | 向下取整 |
"""
@dauthor : cpucode
@date : 2022/2/28 15:11
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = 22
b = 11
c = 0
c = a + b
print("a + b = ", c)
c = a - b
print("a - b = ", c)
c = a * b
print("a * b = ", c)
c = a / b
print("a / b = ", c)
c = a % b
print("a % b = ", c)
# 修改变量 a 、b 、c
a = 2
b = 3
c = a ** b
print("a ** b = ", c)
a = 10
b = 5
c = a // b
print("a//b = ", c)
取模定理
一个正整数 n 而言 :
n = k * p + r
n 可以被拆分成最多 k 个 p 并且余下一个 r
n % p = r
取余运算
对正整数 : 取模运算和取余运算没有区别
对负整数区别:
- 取余公式中的 k 要向 0 靠拢
- 取模公式中的 k 要向负无穷 ( -∞ ) 靠拢
运算方式 | 求 k | 运算式 | 运算答案 |
---|---|---|---|
13 对 3 取模 | k = 13 / 3 = 4.3333,k 向负无穷 ( -∞ ) 靠拢,4.333 取 4 | 13 = 4 * 3 + 1 | 1 |
-13 对 3 取模 | k = -13 / 3 = -4.3333,k 向负无穷 ( -∞ ) 靠拢,-4.333 取 -5 | (-13) = -5 * 3 + 2 | 2 |
13 对 -3 取模 | k = 13 / -3 = -4.3333,k 向负无穷 ( -∞ ) 靠拢,-4.333 取 -5 | 13 = (-5) * (-3) - 2 | -2 |
-13 对 -3 取模 | k = -13 / -3 = 4.3333,k 向负无穷 ( -∞ ) 靠拢,4.333 取 4 | (-13) = 4 * (-3) - 1 | -1 |
13 对 3 取余 | k = 13 / 3 = 4.3333,k 向 0 靠拢,4.333 取 4 | 13 = 4 * 3 + 1 | 1 |
-13 对 3 取余 | k = -13 / 3 = -4.3333,k 向 0 靠拢,-4.333 取 -4 | (-13) = (-4) * 3 - 1 | -1 |
13 对 -3 取余 | k = 13 / -3 = -4.3333,k 向 0 靠拢,-4.333 取 -4 | 13 = (-4) * (-3) + 1 | 1 |
-13 对 -3 取余 | k = -13 / -3 = 4.3333,k 向 0 靠拢,4.333 取 4 | (-13) = 4 * (-3) - 1 | -1 |
比较(关系)运算符
运算符 | 描述 |
---|---|
== | 等于 - 比较对象是否相等 |
!= | 不等于 - 比较两个对象是否不相等 |
> | 大于 - 返回x是否大于y |
< | 小于 - 返回x是否小于y。所有比较运算符返回 1 表示真,返回 0 表示假。这分别与特殊的变量 True 和 False 等价。注意,这些变量名的大写 |
>= | 大于等于 - 返回x是否大于等于y |
<= | 小于等于 - 返回x是否小于等于y |
"""
@dauthor : cpucode
@date : 2022/2/28 15:20
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = 22
b = 11
c = 0
if (a == b):
print("a 等于 b")
else:
print("a 不等于 b")
print("/***************************************/")
if (a != b):
print("a 不等于 b")
else:
print(" a 等于 b")
print("/***************************************/")
if (a < b):
print("a 小于 b")
else:
print("a 大于等于 b")
print("/***************************************/")
if (a > b):
print("a 大于 b")
else:
print("a 小于等于 b")
print("/***************************************/")
# 修改变量 a 和 b 的值
a = 5
b = 20
if (a <= b):
print("a 小于等于 b")
else:
print("a 大于 b")
print("/***************************************/")
if (b >= a):
print("b 大于等于 a")
else:
print("b 小于 a")
赋值运算符
运算符 | 描述 |
---|---|
= | 简单的赋值运算符 |
+= | 加法赋值运算符 |
-= | 减法赋值运算符 |
*= | 乘法赋值运算符 |
/= | 除法赋值运算符 |
%= | 取模赋值运算符 |
**= | 幂赋值运算符 |
//= | 取整除赋值运算符 |
:= | 海象运算符,可在表达式内部为变量赋值。Python3.8 版本新增运算符 |
"""
@dauthor : cpucode
@date : 2022/3/1 8:50
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = 22
b = 11
c = 0
c = a + b
print("a + b = ", c)
c += a
print("c += a = ", c)
c *= a
print("c *= a = ", c)
c /= a
print("c /= a = ", c)
c = 2
print("cc = 2 = ", c)
c **= a
print("c **= a = ", c)
c //= a
print("c //= a = ", c)
交换两个整数
a = input()
b = input()
print("a = {}, b = {}".format(b, a))
位运算符
运算符 | 描述 |
---|---|
& | 按位与运算符:参与运算的两个值, 如果两个相应位都为1, 则该位的结果为1, 否则为0 |
| | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1 |
^ | 按位异或运算符:当两对应的二进位相异时,结果为1 |
~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。~x 类似于 -x-1 |
<< | 左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补 0 |
>> | 右移动运算符:把 “>>” 左边的运算数的各二进位全部右移若干位,">>" 右边的数指定移动的位数 |
"""
@dauthor : cpucode
@date : 2022/3/1 8:54
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = 22
b = 11
c = 0
c = a & b
print("a & b = ", c)
c = a | b
print("a | b = ", c)
c = a ^ b
print("a ^ b = ", c)
c = ~a
print("~a = ", c)
c = a << 2
print("a << 2 = ", c)
c = a >> 2
print("a >> 2 = ", c)
逻辑运算符
运算符 | 逻辑表达式 | 描述 |
---|---|---|
and | x and y | 布尔"与" - 如果 x 为 False,x and y 返回 x 的值,否则返回 y 的计算值 |
or | x or y | 布尔"或" - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值 |
not | not x | 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True |
"""
@dauthor : cpucode
@date : 2022/3/1 8:59
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = 22
b = 11
if(a and b):
print("a 和 b 都为 true")
else:
print("a 和 b 有一个不为 true")
if(a or b):
print("其中一个变量为 true")
else:
print("a 和 b 都不为 true")
print("/***************************************************/")
# 修改变量 a 的值
a = 0
if(a and b):
print("a 和 b 都为 true")
else:
print("a 和 b 有一个不为 true")
if(a or b):
print("其中一个变量为 true")
else:
print("a 和 b 都不为 true")
if not(a and b):
print("其中一个变量为 false")
else:
print("a 和 b 都为 true")
成员运算符
运算符 | 描述 |
---|---|
in | 如果在指定的序列中找到值返回 True,否则返回 False |
not in | 如果在指定的序列中没有找到值返回 True,否则返回 False |
"""
@dauthor : cpucode
@date : 2022/3/1 9:06
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = 22
b = 11
list = [11, 22, 33, 44, 55]
if (a in list):
print("a 在列表 list 中")
else:
print("a 不在列表 list 中")
if(b not in list):
print("b 不在列表 list 中")
else:
print("b 在列表 list 中")
print("/*****************************************/")
# 修改变量 a 的值
a = 2
if (a in list):
print("a 在列表 list 中")
else:
print("a 不在列表 list 中")
身份运算符
运算符 | 描述 |
---|---|
is | is 是判断两个标识符是不是引用自一个对象 |
is not | is not 是判断两个标识符是不是引用自不同对象 |
"""
@dauthor : cpucode
@date : 2022/3/1 9:12
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = 22
b = 22
if(a is b):
print("a 和 b 有相同的标识")
else:
print("a 和 b 没有相同的标识")
if(id(a) == id(b)):
print("a 和 b 有相同的标识")
else:
print("a 和 b 没有相同的标识")
print("/***************************************/")
# 修改变量 b 的值
b = 33
if(a is b):
print("a 和 b 有相同的标识")
else:
print("a 和 b 没有相同的标识")
if(a is not b):
print("a 和 b 没有相同的标识")
else:
print("a 和 b 有相同的标识")
is 与 == 的区别
- is 判断两个引用是否为同一个对象
- == 判断两个引用的值是否相等
- 整数 : (整数区间 [-5, 256] 的常量)引用的都是同一个对象(类似 Java 中的常量池)
str1 = "abc"
str2 = str1
str3 = "".join(["a", "b", "c"])
print(str1, str2, str3)
print(str1 is str2)
print(str1 == str2)
print(str1 is str3)
print(str1 == str3)
a = 256
b = 256
print(a is b)
a = 257
b = 257
print(a is b)
a = -5
b = -5
print(a is b)
a = -6
b = -6
print(a is b)
运算符优先级
运算符 | 描述 |
---|---|
** | 指数 (最高优先级) |
~ + - | 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
* / % // | 乘,除,求余数和取整除 |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位 ‘AND’ |
^ | | 位运算符 |
<= < > >= | 比较运算符 |
== != | 等于运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not and or | 逻辑运算符 |
"""
@dauthor : cpucode
@date : 2022/3/1 9:19
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
a = 22
b = 11
c = 10
d = 5
e = 0
e = (a + b) * c / d
print("(a + b) * c / d = ", e)
e = ((a + b) * c) / d
print("((a + b) * c) / d = ", e)
e = (a + b) * (c / d)
print("(a + b) * (c / d) = ", e)
e = a + (b * c) / d
print("a + (b * c) / d = ", e)
x = True
y = False
z = False
if x or y and z:
print("yes")
else:
print("no")
数字
Python 数字数据类型用于存储数值
数据类型是不允许改变的 , 所以改变数字数据类型的值,将重新分配内存空间
Python 支持三种不同的数值类型:
- 整型(int) - 通常被称为是整型或整数,是正或负整数,不带小数点
- 浮点型(float) - 浮点型由整数部分与小数部分组成
- 复数( (complex)) - 复数由实数部分和虚数部分构成
Python 支持复数,复数由实数部分和虚数部分构成,可以用
a + bj
, 或complex(a,b)
表示, 复数的实部a和虚部b都是浮点型
数字类型转换
对数据内置的类型进行转换,数据类型的转换,只将数据类型作为函数名
- int(x) : 将 x 转换为一个整数
- float(x) : 将 x 转换到一个浮点数
- complex(x) : 将 x 转换到一个复数,实数部分为 x,虚数部分为 0
- complex(x, y) : 将 x 和 y 转换到一个复数,实数部分为 x,虚数部分为 y。x 和 y 是数字表达式
数字运算
解释器可以作为一个简单的计算器,您可以在解释器里输入一个表达式,它将输出表达式的值
在不同的机器上浮点运算的结果可能会不一样
在整数除法中,除法 /
总是返回一个浮点数,如想要整数的结果,丢弃分数部分,可以使用运算符 //
随机数函数
随机数可以用于数学,游戏,安全等领域中,还经常被嵌入到算法中,用以提高算法效率,并提高程序的安全性
数学常量
常量 | 描述 |
---|---|
pi | 数学常量 pi(圆周率,一般以π来表示) |
e | 数学常量 e,e即自然常数(自然常数) |
数学函数
函数 | 返回值 ( 描述 ) |
---|---|
abs(x) | 返回数字的绝对值,如 abs(-10) 返回 10 |
ceil(x) | 返回数字的上入整数,如 math.ceil(4.1) 返回 5 |
cmp(x, y) | 如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 Python3 已废弃,使用 (x>y)-(x<y)。 |
exp(x) | 返回 e 的 x 次幂 (ex) 如 math.exp(1) 返回 2.718281828459045 |
fabs(x) | 以浮点形式返回数字的绝对值,如 math.fabs(-10) 返回 10.0 |
floor(x) | 返回数字的下舍整数,如 math.floor(4.9) 返回 4 |
log(x) | 如 math.log(math.e) 返回 1.0,math.log(100,10) 返回 2.0 |
log10(x) | 返回以 10 为基数的 x 的对数,如 math.log10(100) 返回 2.0 |
max(x1, x2,…) | 返回给定参数的最大值,参数可以为序列 |
min(x1, x2,…) | 返回给定参数的最小值,参数可以为序列 |
modf(x) | 返回 x 的整数部分与小数部分,两部分的数值符号与 x 相同,整数部分以浮点型表示。math.modf(1.5) 返回 (0.5, 1.0) |
pow(x, y) | x ** y 运算后的值。math.pow(2, 7) 返回 128.0 |
round(x, n) | 返回浮点数 x 的四舍五入值,如给出 n 值,则代表舍入到小数点后的位数。其实准确的说是保留值将保留到离上一位更近的一端。 |
sqrt(x) | 返回数字x的平方根。math.sqrt(9) 返回 3.0 |
字符串
字符串是 Python 中最常用的数据类型。使用引号( '
或 "
)来创建字符串
访问字符串中的值
Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用
Python 访问子字符串,可以使用方括号 []
来截取字符串
变量[头下标:尾下标]
索引值以 0 为开始值,-1 为从末尾的开始位置
转义字符
在字符中使用特殊字符时,python 用反斜杠 \
转义字符
转义字符 | 描述 |
---|---|
\ (在行尾时) | 续行符 |
\\ | 反斜杠符号 |
\’ | 单引号 |
\" | 双引号 |
\a | 响铃 |
\b | 退格(Backspace) |
\000 | 空 |
\n | 换行 |
\v | 纵向制表符 |
\t | 横向制表符 |
\r | 回车,将 \r 后面的内容移到字符串开头,并逐一替换开头部分的字符,直至将 \r 后面的内容完全替换完成 |
\f | 换页 |
\yyy | 八进制数,y 代表 0~7 的字符,例如:\012 代表换行 |
\xyy | 十六进制数,以 \x 开头,y 代表的字符,例如:\x0a 代表换行 |
\other | 其它的字符以普通格式输出 |
根据行边界符拆分字符串并找出最长行
实现 splitlines 函数功能:将一段文字按行边界符拆分为列表 , 返回长度最大的字符串
src = "ab c\n\nde fg\rkl\r\n"
data = src.splitlines()
data.sort(key=len, reverse=True)
print(data[0])
字符串运算符
操作符 | 描述 |
---|---|
+ | 字符串连接 |
* | 重复输出字符串 |
[] | 通过索引获取字符串中字符 |
[ : ] | 截取字符串中的一部分,遵循左闭右开原则,str[0:2] 是不包含第 3 个字符的。 |
in | 成员运算符 - 如果字符串中包含给定的字符返回 True |
not in | 成员运算符 - 如果字符串中不包含给定的字符返回 True |
r/R | 原始字符串 - 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(可以大小写)以外,与普通字符串有着几乎完全相同的语法。 |
% | 格式字符串 |
a = 'cpu'
b = 'code'
print('\na + b :', a + b)
print('a * 2 :', a * 2)
print('a[1] :', a[1])
print('a[1:4] :', a[1:4])
print('\n"c" in a :', "c" in a)
print('"c" not in a :', "c" not in a)
字符串格式化
符 号 | 描述 |
---|---|
%c | 格式化字符及其ASCII码 |
%s | 格式化字符串 |
%d | 格式化整数 |
%u | 格式化无符号整型 |
%o | 格式化无符号八进制数 |
%x | 格式化无符号十六进制数 |
%X | 格式化无符号十六进制数(大写) |
%f | 格式化浮点数字,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 作用同%e,用科学计数法格式化浮点数 |
%g | %f和%e的简写 |
%G | %f 和 %E 的简写 |
%p | 用十六进制数格式化变量的地址 |
name = 'cpu'
position = '学生'
address = "cs"
print("姓名:%s" % name)
print("职位:%s" % position)
print("地址:%s" % address)
符号 | 功能 |
---|---|
* | 定义宽度或者小数点精度 |
- | 用做左对齐 |
+ | 在正数前面显示加号( + ) |
<sp> | 在正数前面显示空格 |
# | 在八进制数前面显示零(‘0’),在十六进制前面显示’0x’或者’0X’(取决于用的是’x’还是’X’) |
0 | 显示的数字前面填充’0’而不是默认的空格 |
% | ‘%%‘输出一个单一的’%’ |
(var) | 映射变量(字典参数) |
m.n. | m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话) |
三引号
python 三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符
f-string
f-string 是 python3.6 之后版本添加的 ( 字面量格式化字符串 ) ,是新的格式化字符串的语法
f-strings 以字母 f
或 F
为前缀 , 格式化字符串使用一对单引号、双引号、三单引号、三双引号. 格式化字符串中
name = 'cpuCode'
age = 22
format_string1 = f'我叫{name}, {age}岁'
format_string2 = f"我叫{name}, {age}岁"
format_string3 = F'''我叫{name}, {age}岁'''
format_string4 = F"""我叫{name}, {age}岁"""
format_string5 = f'3 + 5 = {3 + 5}'
a = 10
b = 20
format_string6 = f'10 + 20 = {a + b}'
# 两个花括号会被替换为一个花括号, 注意{{}} 不表示表达式
format_string7 = F'我叫{{name}}, {{age}}岁'
print(format_string1)
print(format_string2)
print(format_string3)
print(format_string4)
print(format_string5)
print("/*************************************/")
print(format_string6)
print(format_string7)
计算x秒后的时间
# hh:mm:ss,x 作为标准输入从控制台输入
hh, mm, ss = map(int, input().strip('\n').split(':'))
x = eval(input())
# 对 ss + x 同时进行取模和整除操作
# divmod会返回商和余数2个参数
x, new_ss = divmod(x + ss, 60)
x, new_mm = divmod(x + mm, 60)
x, new_hh = divmod(x + hh, 24)
print(f'{new_hh:0>2d}:{new_mm:0>2d}:{new_ss:0>2d}')
字符串输入
通过 input 完成从键盘获取数据,然后保存到指定的变量中
input获取的数据,都以字符串的方式进行保存,即使输入的是数字,那么也是以字符串方式保存
username = input('请输入用户名:')
print('用户名为:%s' % username)
password = input('请输入密码:')
print("密码为:%s" % password)
下标和切片
下标索引
下标 ( 编号 ) ,如 : 超市中的存储柜的编号,通过编号就能找到相应的存储空间
字符串中 ( 下标 )
列表与元组支持下标索引,字符串实际上就是字符的数组,所以支持下标索引
字符串 : name = ‘abcdef’ , 内存中的实际存储 :
name = 'abcdef'
print(name[0])
print(name[1])
print(name[5])
切片
切片是指对操作的对象截取其中一部分的操作 ( 字符串、列表、元组 )
切片的语法:[起始:结束:步长]
选取的区间从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身),步长表示选取间隔
name = '123456'
print(name[0:3])
print(name[0:5])
print(name[3:5])
print(name[2:])
print(name[1:-1])
print(name[::2])
print(name[::-1])
Unicode 字符串
在Python2中
- 普通字符串是以 8 位 ASCII 码进行存储的
- Unicode 字符串存储为 16 位 unicode 字符串,可以表示更多的字符集 ( 字符串前面加上前缀 u )
在Python3中,所有的字符串都是 Unicode 字符串
字符串内建函数
方法 | 解释 |
---|---|
capitalize() | 将字符串的第一个字符转换为大写 |
center(width, fillchar) | 返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格 |
count(str, beg= 0,end=len(string)) | 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数 |
bytes.decode(encoding=“utf-8”, errors=“strict”) | Python3 中 str 没有 decode 方法,但我们可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回 |
encode(encoding=‘UTF-8’,errors=‘strict’) | 以 encoding 指定的编码格式编码字符串,如果出错默认报一个 ValueError 的异常,除非 errors 指定的是 ‘ignore’ 或者 ‘replace’ |
endswith(suffix, beg=0, end=len(string)) | 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False |
expandtabs(tabsize=8) | 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8 |
find(str, beg=0, end=len(string)) | 检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回 -1 |
index(str, beg=0, end=len(string)) | 跟 find() 方法一样,只不过如果 str 不在字符串中会报一个异常 |
isalnum() | 如果字符串至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False |
isalpha() | 如果字符串至少有一个字符并且所有字符都是字母或中文字则返回 True,否则返回 False |
isdigit() | 如果字符串只包含数字则返回 True 否则返回 False |
islower() | 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False |
isnumeric() | 如果字符串中只包含数字字符,则返回 True,否则返回 False |
isspace() | 如果字符串中只包含空白,则返回 True,否则返回 False |
istitle() | 如果字符串是标题化的则返回 True,否则返回 False |
isupper() | 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False |
join(seq) | 以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串 |
len(string) | 返回字符串长度 |
ljust(width[, fillchar]) | 返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格 |
lower() | 转换字符串中所有大写字符为小写 |
lstrip() | 截掉字符串左边的空格或指定字符 |
maketrans() | 创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标 |
max(str) | 返回字符串 str 中最大的字母 |
min(str) | 返回字符串 str 中最小的字母 |
replace(old, new [, max]) | 将字符串中的 old 替换成 new,如果 max 指定,则替换不超过 max 次 |
rfind(str, beg=0,end=len(string)) | 类似于 find() 函数,不过是从右边开始查找 |
rindex( str, beg=0, end=len(string)) | 类似于 index(),不过是从右边开始 |
rjust(width,[, fillchar]) | 返回一个原字符串右对齐,并使用 fillchar(默认空格)填充至长度 width 的新字符串 |
rstrip() | 删除字符串末尾的空格或指定字符 |
split(str="", num=string.count(str)) | 以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串 |
splitlines([keepends]) | 按照行(’\r’,’\r\n’,’\n’)分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符 |
startswith(substr, beg=0,end=len(string)) | 检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查 |
strip([chars]) | 在字符串上执行 lstrip()和 rstrip() |
swapcase() | 将字符串中大写转换为小写,小写转换为大写 |
title() | 返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写 |
translate(table, deletechars="") | 根据 str 给出的表(包含 256 个字符)转换 string 的字符,要过滤掉的字符放到 deletechars 参数中 |
upper() | 转换字符串中的小写字母为大写 |
zfill(width) | 返回长度为 width 的字符串,原字符串右对齐,前面填充 0 |
isdecimal() | 检查字符串是否只包含十进制字符,如果是返回 True,否则返回 False |
find 检测 str 是否包含在 str 中
mystr = 'cpuCode, cpu, code'
mystr.find('code')
mystr.find('cpu', 0, 10)
index 检测 str 是否包含在 str 中
如果 str 不在 str 中会报一个异常
mystr = 'cpuCode, cpu, code'
mystr.index('cpu', 0, 10)
mystr.index('cpuTest', 0, 10)
count 在 string 里面出现的次数
mystr = 'cpuCode, cpu, code'
mystr.count('cpu')
mystr.count('cpu', 0, 10)
replace 把 mystr 中的 str1 替换成 str2
count 指定,则替换不超过 count 次
mystr = 'cpuCode, cpu, code'
mystr.replace('cpu', 'CPU')
mystr.replace('cpu', 'CPU', 1)
split 以 str 为分隔符切片 mystr
maxsplit 有指定值,则仅分隔 maxsplit + 1 个子字符串
mystr = 'cpuCode, cpu, code'
mystr.split(" ")
mystr.split(' ', 2)
join 将 mystr 插入到 str 中每个元素之间
str = ' '
li = ['cpu', 'code', 'cpuCode']
str.join(li)
str = "_"
str.join(li)
capitalize 将字符串的第一个字符转换为大写
mystr = 'cpuCode, cpu, code'
mystr.capitalize()
title 把字符串的每个单词首字母大写
mystr = 'cpuCode, cpu, code'
mystr.title()
startswith 检查字符串是否是以 str 开头
mystr = 'cpuCode, cpu, code'
mystr.startswith('cpu')
mystr.startswith('code')
endswith 检查字符串是否以 obj 结束
mystr = 'cpuCode, cpu, code'
mystr.startswith('code')
mystr.startswith('cpu')
lower 转换 str 中所有大写字符为小写
mystr = 'cpuCode, cpu, code'
mystr.lower()
upper 转换 str 中的小写字母为大写
mystr = 'cpuCode, cpu, code'
mystr.upper()
统计字符串出现的次数
str_1 = 'Fasten your seatbelts. It is going to be a bumpy night.'
# 字符串 str_1,
# 统计字符 a 在字符串中出现的次数
# 统计字符 going 在字符串 0 到 40 范围之间的次数
a_sum = str_1.count('a')
g_sum = str_1.count('going', 0, 40)
print(a_sum, g_sum)
列表
序列是 Python 中最基本的数据结构
序列中的每个值都有对应的位置值( 索引 ),第一个索引是 0,第二个索引是 1,依此类推
Python 有 6 个序列的内置类型,但最常见的是列表和元组
列表都可以进行的操作包括索引,切片,加,乘,检查成员
Python 已经内置确定序列的长度以及确定最大和最小的元素的方法
列表是最常用的 Python 数据类型,它可以作为一个方括号内的逗号分隔值出现
列表的数据项不需要具有相同的类型
创建一个列表,只要把逗号 ,
分隔的不同的数据项使用方括号 []
访问列表中的值
与字符串的索引一样,列表索引从 0 开始,第二个索引是 1,依此类推
通过索引列表可以进行截取、组合等操作
索引也可以从尾部开始,最后一个元素的索引为 -1,往前一位为 -2,以此类推
使用下标索引来访问列表中的值,同样你也可以使用方括号 [] 的形式截取字符
namesList = ['cpuCode', 'cpu', 'code']
print(namesList[0])
print(namesList[1])
print(namesList[2])
for name in namesList:
print(name)
length = len(namesList)
i = 0
while i < length:
print(namesList)
i += 1
列表的嵌套
列表支持嵌套
列表的嵌套 : 一个列表中的元素又是一个列表
import random
# 定义一个列表用来保存3个办公室
offices = [[],[],[]]
# 定义一个列表用来存储8位老师的名字
names = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
for name in names:
index = random.randint(0, 2)
offices[index].append(name)
i = 1
for temp_names in offices:
print('办公室 %d 的人数为: %d' % (i, len(temp_names)))
i += 1
for name in temp_names:
print("%s" % name, end = '')
print("\n")
print("-" * 20)
列表函数
append 添加元素
#定义变量A,默认有3个元素
A = ['cpu', 'cpuCode', 'code']
print("-----添加之前,列表A的数据-----")
for temp_name in A:
print(temp_name)
#提示、并添加元素
temp = input('请输入要添加的学生姓名:')
A.append(temp)
print("-----添加之后,列表A的数据-----")
for temp_name in A:
print(temp_name)
extend 将另一个集合中的元素逐一添加到列表中
a = [1, 2]
b = [3, 4]
a.append(b)
a.extend(b)
insert 在指定位置 index 前插入元素 object
a = [0, 1, 2]
a.insert(1, 3)
通过下标来修改
#定义变量A,默认有3个元素
A = ['cpu','cpuCode','code']
print("-----修改之前,列表A的数据-----")
for temp_name in A:
print(temp_name)
#修改元素
A[1] = 'liubi'
print("-----修改之后,列表A的数据-----")
for temp_name in A:
print(temp_name)
in, not in 指定的元素是否存在
in(存在), 如果存在 , 为 true,否则为 false
not in(不存在),如果不存在 , 为true,否则 false
#待查找的列表
name_list = ['cpu','cpuCode','code']
#获取用户要查找的名字
find_name = input('请输入要查找的姓名:')
#查找是否存在
if find_name in name_list:
print('在字典中找到了相同的名字')
else:
print('没有找到')
index , count 指定的元素是否存在
a = ['a', 'b', 'c', 'a', 'b']
a.index('a', 1, 3) # 注意是左闭右开区间
a.index('a', 1, 4)
a.count('b')
a.count('d')
del 下标删除
names = ['cpu', 'cpuCode', 'code']
print('------删除之前------')
for name in names:
print(name)
del names[1]
print('------删除之后------')
for name in names:
print(name)
pop 删除最后一个元素
names = ['cpu', 'cpuCode', 'code']
print('------删除之前------')
for name in names:
print(name)
names.pop()
print('------删除之后------')
for name in names:
print(name)
remove 根据元素的值进行删除
names = ['cpu', 'cpuCode', 'code']
print('------删除之前------')
for name in names:
print(name)
names.remove('cpu')
print('------删除之后------')
for name in names:
print(name)
sort , reverse 排序
sort : 将 list 按特定顺序重新排列,默认为由小到大,参数reverse=True可改为倒序,由大到小
reverse 方法是将 list 逆置
a = [1, 4, 3, 2]
a.reverse()
a.sort()
a.sort(reverse=True)
元组
元组是序列 , 元素不能修改
元组使用小括号
列表使用方括号
访问元组
tuple = ('cpu', 10, 2.3)
tuple[0]
tuple[1]
tuple[2]
修改元组
python中不允许修改元组的数据,包括不能删除其中的元素
tuple = ('cpu', 10, 2.3)
tuple[0] = 'cpuCode'
元组索引,截取
a = ('a', 'b', 'c', 'a', 'b')
# 注意是左闭右开区间
a.index('a', 1, 3)
a.index('a', 1, 4)
a.count('b')
a.count('d')
Set(集合)
集合是无序集合。每个元素都是唯一的(没有重复项),并且必须是不可变的(不能更改)
集合可用于执行数学集合运算,如 : 并集,交集,对称差等
创建集合 set()
, 把 所有元素放在大括号 {}
中并用逗号分隔或使用内置函数
具有任意数量的项目,且具有不同的类型(整数,浮点数,元组,字符串等)。但是集合不能具有可变元素(如 list ,set 或 dictionary)作为其元素
dic1 = {1, 2, 3}
dic2 = {1.0, (1, 2, 3), 'cpuCode'}
print(dic1)
print(dic2)
创建一个空集
# 用{}初始化
a = {}
# 检查a的数据类型
print(type(a))
# 初始化使用 set()
a = set()
# 检查a的数据类型
print(type(a))
更改集合
- add() : 添加单个元素
- update() : 添加多个元素
- update() : 采用元组,列表,字符串或其他集合作为其参数
# 初始化 my_set
my_set = {1, 3}
print(my_set)
# 增加一个元素
my_set.add(2)
print(my_set)
# 增加多个元素
my_set.update([2,3,4])
print(my_set)
# 增加 list 和set
my_set.update([4,5], {1, 6, 8})
print(my_set)
删除元素
discard()
和 remove()
方法从集合中删除特定项目
discard()
: 项目不存在于集合中,保持不变
remove()
: 不存在于集合中 , 引发错误
# 初始化 my_set
my_set = {1, 3, 4, 5, 6}
print(my_set)
# 抛弃一个元素
my_set.discard(4)
print(my_set)
# 移除一个元素
my_set.remove(6)
print(my_set)
# 抛弃一个元素
my_set.discard(2)
print(my_set)
pop()
: 删除并返回一个项目 , 集合为无序,任意弹出clear()
: 删除集合中的所有项目
# 初始化 my_set
my_set = set("cpuCode")
print(my_set)
# pop一个元素
# 输出: 随机元素
print(my_set.pop())
# pop 任意元素
my_set.pop()
print(my_set)
# 清空 my_set
my_set.clear()
print(my_set)
集合并集
A 和 B 的并集 : 集合的所有元素的集合
- 并集 :
|
操作符 - 并集 :
union()
方法
# 初始化 A 和 B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# 使用 | 运算符
print(A | B)
# 初始化 A 和 B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# 使用union 函数
print(A.union(B))
# 在B上使用并集函数
print(B.union(A))
集合相交
A 和 B 的交集 : 在集合中共有的一组元素
- & 运算符
- intersection() 方法
# 初始化 A 和 B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# 使用 & 运算符
print(A & B)
# 初始化 A 和 B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# 在A上使用交集函数
print(A.intersection(B))
# 在B上使用交集函数
print(B.intersection(A))
集合差异
A 和 B 的差 A - B : 仅在 A 中但不在 B 中的一组元素
-
运算符difference()
方法
# 初始化 A 和 B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# 在A上使用 - 运算符
print(A - B)
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# 在A上使用差异函数
print(A.difference(B))
# 在B上使用-运算符符
print(B - A)
# 在B上使用差异函数
print(B.difference(A))
集合对称差异
A 和 B 的对称差异 : A 和 B 中的一组元素,但两者中的元素相同
^
运算符symmetric_difference()
方法
# 初始化 A 和 B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# 使用 ^ 运算符
print(A ^ B)
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# 在A上使用symmetric_difference函数
print(A.symmetric_difference(B))
# 在B上使用symmetric_difference函数
print(B.symmetric_difference(A))
内建函数
方法 | 描述 |
---|---|
add() | 将元素添加到集合中 |
clear() | 从集合中删除所有元素 |
copy() | 返回集合的副本 |
difference() | 返回两个或多个集合的差作为新集合 |
difference_update() | 从该集合中删除另一个集合的所有元素 |
discard() | 如果元素是成员,则从集合中删除它(如果元素不在集合中,则不执行任何操作) |
intersection() | 返回两个集合的交集作为新集合 |
intersection_update() | 用自身和另一个的交集更新集合 |
isdisjoint() | True 如果两个集合的交点为空,则返回 |
issubset() | 返回 True 另一个集合是否包含此集合 |
issuperset() | 返回 True 此集合是否包含另一个集合 |
pop() | 删除并返回一个任意的 set 元素。提高 KeyError,如果集合为空 |
remove() | 从集合中删除一个元素。如果元素不是成员,则引发一个 KeyError |
symmetric_difference() | 将两个集合的对称差作为新集合返回 |
symmetric_difference_update() | 用本身和另一个的对称差异更新一个集合 |
union() | 返回新集合中集合的并集 |
update() | 用自身和其他元素的并集更新集合 |
功能 | 描述 |
---|---|
all() | 如果集合的所有元素都为 True(或者集合为空),则返回 True |
any() | 如果集合中的任何元素为 True,则返回 True。 如果集合为空,则返回False |
enumerate() | 返回一个枚举对象。它包含成对的所有项的索引和值 |
len() | 返回集合中的长度(项目数) |
max() | 返回集合中最大的项目 |
min() | 返回集合中最小的项目 |
sorted() | 从集合中的元素返回一个新的排序列表(不对集合本身进行排序) |
sum() | 返回集合中所有元素的总和 |
Frozenset
Frozenset 是具有集合特征的新类,但是一旦分配,就不能更改其元素
元组是不可变列表,而冻结集是不可变集
frozenset 是可哈希化的,可用作字典的键
# 初始化 A 和 B
A = frozenset([1, 2, 3, 4])
B = frozenset([3, 4, 5, 6])
print(A.isdisjoint(B))
print(A.difference(B))
print(A | B)
字典
字典是另一种可变容器模型,且可存储任意类型对象
字典的每个键值 key=>value
对用冒号 :
分割,每个对之间用逗号( ,
)分割,整个字典包括在花括号 {}
中
dict 作为 Python 的关键字和内置函数,变量名不建议命名为 dict
键必须是唯一的,但值则不必
值可以取任何数据类型,但键必须是不可变的,如字符串,数字
- 字典和列表一样,也能够存储多个数据
- 列表中找某个元素时,是根据下标进行
- 字典中找某个元素时,是根据 ’ 名字 ’
- 字典的每个元素由 2 部分组成,键 : 值
访问字典里的值
info = {'name':'cpu', 'id':100, 'sex':'f', 'address':'cs'}
print(info['name'])
print(info['address'])
print(info['age'])
# 不确定字典中是否存在某个键,get
age = info.get('age')
type(age)
# 若info中不存在'age'这个键,就返回默认值18
age = info.get('age', 18)
print(age)
修改字典
字典的每个元素中的数据是可以修改,只要通过 key 找到,即可修改
info = {'name':'cpu', 'id':100, 'sex':'f', 'address':'cs'}
new_id = input('请输入新的学号')
info['id'] = int(new_id)
print('修改之后的 id 为 %d :' % info['id'])
删除字典元素
删单一的元素也能清空字典,清空只需一项操作
显式删除一个字典用del命令
遍历
通过 for ... in ...
我们可以遍历字符串、列表、元组、字典等
字符串遍历
a_str = "cpu, code, cpuCode"
for char in a_str:
print(char, end = ' ')
列表遍历
a_list = [1, 2, 3, 4, 5]
for num in a_list:
print(num, end = ' ')
元组遍历
a_turple = (1, 2, 3, 4, 5)
for num in a_turple:
print(num, end = ' ')
字典遍历
dict = {'name': 'cpuCode', 'sex':'m'}
# 遍历字典的key
for key in dict.keys()
print(key)
# 遍历字典的value
for value in dict.values()
print(value)
# 遍历字典的项
for item in dict.items
print(item)
# 遍历字典的 key-value
for key, value in dict.items
print("key = %s , value = %s" % (key, value))
字典内置函数
方法 | 作用 |
---|---|
clear() | 删除字典内所有元素 |
copy() | 返回一个字典的浅复制 |
fromkeys() | 创建一个新字典,以序列 seq 中元素做字典的键 |
get(key) | 返回指定键的值,如果键不在字典中,则返回 default 值 |
items() | 以列表返回可遍历的(键, 值)元组对 |
keys() | 以列表返回字典所有的键 |
values() | 以列表返回字典所有的值 |
pop(key) | 删除并返回指定 key 的值 |
popitem() | 删除并返回字典的最后一个键值对,不接受参数 |
setdefault(key, default=None) | 和 get() 类似,但如果键不存在于字典中,将会添加键并将值设为 default |
update(dict2) | 把字典 dict2 的键/值对更新到 dict 里 |
enumerate 将可遍历的数据对象组合为索引序列
chars = ['a', 'b', 'c']
for i, chr in enumerate(chars):
print i, chr
len 键值对的个数
dict = {'name': 'cpuCode', 'sex':'m'}
len(dict)
keys 所有KEY的列表
dict = {'name': 'cpuCode', 'sex':'m'}
dict.keys()
values 所有value的列表
dict = {'name': 'cpuCode', 'sex':'m'}
dict.values()
items 所有(键,值)元祖的列表
dict = {'name': 'cpuCode', 'sex':'m'}
dict.items()
判断
如果某些条件满足,才能做某件事情;条件不满足时,则不能做,这就是所谓的判断
if 基本格式
if 语句是用来进行判断
if 要判断的条件:
条件成立时,要做的事情
age = 30
if age >= 18:
print("cpuCode 流弊")
if-else
if 条件:
满足条件时要做的事情1
满足条件时要做的事情2
满足条件时要做的事情3
...(省略)...
else:
不满足条件时要做的事情1
不满足条件时要做的事情2
不满足条件时要做的事情3
...(省略)...
chePiao = 1
if chePiao == 1:
print(" == 1")
else:
print("!= 1")
if…elif…else…
- elif 必须和 if 一起使用,否则出错
- else 一般用在最后,即所有条件都不满足时使用
if xxx1:
事情1
elif xxx2:
事情2
elif xxx3:
事情3
else:
事情4
score = 77
if score >= 90 and score <= 100:
print('本次考试,等级为A')
elif score >= 80 and score < 90:
print('本次考试,等级为B')
elif score >= 70 and score < 80:
print('本次考试,等级为C')
elif score >= 60 and score < 70:
print('本次考试,等级为D')
elif score >= 0 and score < 60:
print('本次考试,等级为E')
三目运算
# 求a和b两个数字中的较大值
a = 10
b = 20
# 使用三目运算符求较大值
max = a if a > b else b
print("较大值为: %d " % max)
if 嵌套
if 条件1:
满足条件1 做的事情1
满足条件1 做的事情2
if 条件2:
满足条件2 做的事情1
满足条件2 做的事情2
- 外层的 if 判断,也可以是 if-else
- 内层的 if 判断,也可以是 if-else
# 用1代表有车票,0代表没有车票
chepiao = 1
# 刀子的长度,单位为cm
dao_lenght = 9
if chepiao == 1:
print("有车票,可以进站")
if dao_lenght < 10:
print("通过安检")
else:
print("没有通过安检")
else:
print("没有车票,不能进站")
判断三角形
从标准输入流(控制台)中获取 a、b、c,它们分别代表三角形的三条边长,判断这三条边是否能组成一个三角形
a = int(input())
b = int(input())
c = int(input())
lis = [a, b, c]
if 2 * max(lis) < sum(lis) :
print("Is a triangle")
else:
print("Not a triangle")
循环
-
while 和 if 的用法基本类似,区别在于:if 条件成立,则执行一次; while 条件成立,则重复执行,直到条件不成立为止
-
需要多次重复执行的代码,都可以用循环的方式来完成
while循环
while 条件:
条件满足时,做的事情1
条件满足时,做的事情2
条件满足时,做的事情3
...(省略)...
i = 0
while i < 5:
print("当前是第 %d 次执行循环" % (i + 1))
print("i = %d" % i)
i += 1
i = 1
sum = 0
while i <= 100:
sum = sum + i
i += 1
print("1-100累加 : %d" % sum)
while循环嵌套
- while 嵌套就是:while 里面还有 while
while 条件1:
条件1满足时,做的事情1
条件1满足时,做的事情2
条件1满足时,做的事情3
...(省略)...
while 条件2:
条件2满足时,做的事情1
条件2满足时,做的事情2
条件2满足时,做的事情3
...(省略)...
i = 1
while i <= 5:
j = 1
while j <= 5:
print("*", end=" ")
j += 1
print()
i += 1
for循环
- 像while循环一样,for可以完成循环的功能
for 临时变量 in 列表或者字符串等可迭代对象:
循环满足条件时执行的代码
name = 'cpuCode'
for x in name:
print(x)
if x == '1':
print('cpu')
for i in range(5):
print(i)
打印九九乘法表
for n in range(1, 10):
for i in range(1, n):
print('{}*{}={}'.format(i, n, n * i), end=' ')
print(f"{n}*{n}={n**2}")
break 和 continue
break
for循环
name = 'cpuCode'
for x in name:
print("--------")
if x == 'e':
break
print(x)
else:
print('==for循环过程中,没有执行 break ==')
while循环
i = 0
while i < 5:
i = i + 1
print('-----------')
if i == 3
break
print(i)
else:
print("==while循环过程中,如果没有执行break退出,则执行本语句==")
- break的作用:立刻结束break所在的循环
continue
for 循环
name = 'cpuCode'
for x in name:
print('------')
if x == 'o':
continue
print(x)
else:
print('while循环过程中,没有break')
while 循环
i = 0
while i < 5:
i = i + 1
print('----')
if i == 3:
continue
print(i)
- continue 的作用:用来结束本次循环,紧接着执行下一次的循环
- break/continue 只能用在循环中,除此以外不能单独使用
- break/continue 在嵌套循环中,只对最近的一层循环起作用
函数
- 把具有独立功能的代码块组织为一个小模块,这就是函数
函数定义和调用
def 函数名():
代码
定义了函数之后,就相当于有了一个具有某些功能的代码,想要执行,通过 函数名() 即可完成调用
# 定义一个函数,能够完成打印信息的功能
def print_info():
print('------------------------------------')
print(' 人生苦短,我用Python')
print('------------------------------------')
print_info()
- 每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕
- 如果函数中执行到了 return 也会结束函数
函数的文档说明
def test(a, b)
"用来完成对2个数求和"
print('%d' % (a + b))
test(11, 22)
help(test)
函数参数
def add2num(a, b):
c = a + b
print c
add2num(11, 22)
add2num(b = 1, a = 2)
add2num(b = 1, 2)
- 定义时小括号中的参数,用来接收参数用的 ( 形参 )
- 调用时小括号中的参数,用来传递给函数用的 ( 实参 )
函数返回值
返回值 : 程序中函数完成一件事情后,最后给调用者的结果
在函数中把结果返回给调用者,需要在函数中使用 return
def add2num(a, b):
c = a + b
return c
result = add2num(10, 20)
print(result)
函数的嵌套调用
def testB():
print('---- testB start----')
print('testB函数执行的代码')
print('---- testB end----')
def testA():
print('---- testA start----')
testB()
print('---- testA end----')
testA()
-
一个函数里面又调用了另外一个函数,这就是所谓的函数嵌套调用
-
函数B 执行完就回到上次 函数A执行的位置
多函数
一个程序往往由多个函数组成
全局变量
g_num = 0
def test1():
global g_num
# 将处理结果存储到全局变量g_num中
g_num = 10
def test2():
print(g_num)
test1()
test2()
函数的返回值、参数
def test1()
# 结果返回
return 10
def test2(num)
# 形参打印
print(num)
# 存到变量result中
result = test1()
test2(result)
函数嵌套调用
def test1()
return 10
def test2()
# test1 返回
result = test1()
# result处理
print(result)
test2()
函数返回值
多个return
def nums():
print('1111')
return 1
print('2222')
return 2
print('3333')
return 3
引用
判断两个变量是否为同一个值的引用
a = 1
b = a
id(a)
id(b)
a = 10
id(a)
id(b)
变量a中存放了100,事实上变量a存储是100的引用
引用当做实参
- Python中函数参数是引用传递
- 不可变类型,因变量不能修改,所以运算不会影响到变量自身
- 可变类型来说,函数体中的运算有可能会更改传入的参数变量
自定义函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段
函数能提高应用的模块性,和代码的重复利用率
定义一个函数要使用 def
语句,依次写出函数名、括号、括号中的参数和冒号 :
,然后,在缩进块中编写函数体,函数的返回值用 return
语句返回
def 函数名(参数列表):
函数体
def hello() :
print("cpu")
hello()
自定义一个求绝对值的 my_abs
函数
def my_abs(x):
if x >= 0:
return x
else:
return -x
print('my_abs(-10):')
print(my_abs(-10))
参数检查
调用函数时,如果参数个数不对,解释器会自动检查出来,并抛出 TypeError
:
def my_abs(x):
if x >= 0:
return x
else:
return -x
print(my_abs(-10, 20))
返回多个值
def cal_rectangle_perimeter_and_area(length, width):
return (length + width) * 2, length * width
perimeter, area = cal_rectangle_perimeter_and_area(4, 3)
result = cal_rectangle_perimeter_and_area(4, 3)
print(f'perimeter = {perimeter}, area = {area}')
print(f'\nresult = {result}')
返回值是一个 tuple , 但是返回一个 tuple 可以省略括号,而多个变量可以同时接收一个 tuple,按位置赋给对应的值,所以函数返回多值 = 返回一个 tuple
匿名函数 lambda
lambda 表达式( 匿名函数 ),常用来表示内部仅包含 1 行表达式的函数
def add(x, y):
return x + y
print(add(3, 4))
name = lambda : x + y
print(add(3, 4))
变量
命名空间
命名空间 : 在项目中避免名字冲突的一种方法
命名空间:
-
内置名称(built-in names): Python 语言内置的名称,如 : 函数名 abs、chr 和异常名称 BaseException、Exception 等
-
全局名称(global names): 模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量
-
局部名称(local names): 函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量(类中定义的也是)
命名空间查找顺序:
- 局部的命名空间
- 全局命名空间
- 内置命名空间
命名空间的生命周期:命名空间的生命周期取决于对象的作用域,如果对象执行完成,该命名空间的生命周期就结束
print(chr) # 访问内置名称 chr
chr = 'chr' # chr 是全局名称
print(chr) # 访问全局名称 chr
def outer_function():
chr = 'char'
print(chr) # 访问局部名称 chr
outer_var = 'out_var'
print(outer_var)
# 无法从外部命名空间访问内部命名空间的对象
# print(inner_var)
def inner_function():
inner_var = 'inner_var'
# 可以从内部命名空间访问外部命名空间的对象
print(outer_var)
print(inner_var)
inner_function()
outer_function()
作用域
直接访问一个变量,从内到外依次访问所有的作用域直到找到,否则会报未定义的错误
Python 的作用域 :
- L(Local):最内层,包含局部变量,如 : 一个函数/方法内部
- E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量
- G(Global):当前脚本的最外层,如 : 当前模块的全局变量
- B(Built-in): 包含了内建的变量/关键字等,最后被搜索
规则顺序: L –> E –> G –> B
在局部找不到,就去局部外的局部找(闭包),再找不到就会去全局找,再者去内置中找
局部变量
- 局部变量 : 在函数内部定义的变量
- 作用范围是这个函数内部,只在这个函数中使用,在函数的外部是不能使用
- 作用范围只是在自己的函数内部,所以不同的函数可以定义相同名字的局部变量
- 局部变量 : 临时保存数据需要在函数中定义变量来进行存储
- 当函数调用时,局部变量被创建,当函数调用完成后这个变量
def test1():
# 局部变量
a = 300
print('test1 a = %d' % a)
a = 400
print('test1 a = %d' % a)
def test2():
# 局部变量
a = 200
print('test2 a = %d' % a)
test1()
test2()
全局变量
全局变量 : 在一个函数中使用,也能在其他的函数中使用
# 定义全局变量
a = 100
def test1():
print(a)
def test2():
print(a)
test1()
test2()
b = 20
def test3():
a = 30
print('test3 a = %d' % a)
a = 40
print('test3 a = %d' % a)
def test4():
print('test4 a = %d' % a)
test3()
test4()
c = 20
def test5():
global c
print('test5 c = %d' % c)
c = 30
print('test5 c = %d' % c)
def test6():
print('test6 c = %d' % c)
test5()
test6()
- 在函数外边定义的变量叫做全局变量
- 全局变量能够在所有的函数中进行访问
- 当函数内出现局部变量和全局变量相同名字时,函数内部中的 变量名 = 数据 , 此时理解为定义了一个局部变量,而不是修改全局变量的值
- 函数中出现
global
全局变量的名字 , 对全局变量进行修改 - 在函数中需要对多个全局变量进行修改,那么可以使用
global
和 nonlocal
关键字
-
global
: 标识该变量是全局变量,对该变量进行修改就是修改全局变量 -
nonlocal
: 标识该变量是上一级函数中的局部变量
num = 1
def function():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
function()
print(num)
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
可变参数传递
列表传递参数:
def cout(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(cout([1, 2, 3]))
元组传递参数:
def cout(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(cout((1, 3, 5, 7)))
使用可变参数
参数前面加了一个 *
号 , 调用该函数时,就传入任意个参数,包括0个参数
def cout(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(cout(1, 2, 3))
print(cout())
# list
my_list = [1, 2, 3]
print(cout(*my_list))
# tuple
my_tuple = (1, 2, 3)
print(cout(*my_tuple))
不可变参数传递
函数 person 除了必选参数 name 和 age 外,还接受关键字参数 **kw
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('cpu', 30)
传入任意个数的关键字参数
def person(name, age, **kw):
print('name: ', name, 'age: ', age, 'other: ', kw)
person('cpu', 22, city='cs')
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('cpucode', 25, gender='M', job='BigData')
先组装出一个 dict,在 dict 转换为关键字参数传进去
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
extra = {'city': 'cs', 'job': 'BigData'}
person('cpu', 24, city=extra['city'], job=extra['job'])
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
extra = {'city': 'cs', 'job': 'BigData'}
person('cpu', 22, **extra)
**extra
表示把 extra 这个 dict 的所有键用关键字参数传入到函数的 **kw
参数,**kw
将获得一个 dict
**kw
获得的 dict 是 extra 的一份拷贝,对**kw
的改动不会影响到函数外的 extra
打印学生平均成绩
设计一个函数 print_avg
,函数接收多个关键字参数作为学生的信息,接收多个数字参数作为学生多次考试的成绩,请从学生信息中提取出学生的 student_name
,student_age
,然后求出这个学生多次考试的平均成绩 Average(保留两位小数),返回一个字符串
def print_avg(*num, **info) :
name = info['student_name']
age = info['student_age']
avg = sum(num)/len(num)
return ('name: {}, age: {}, avg: {:.2f}'.format(name, age, avg))
默认参数
默认值在 定义 作用域里的函数定义中求值
i = 5
def f(arg=i):
print(arg)
i = 6
f()
默认值只计算一次。默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果
函数会累积后续调用时传递的参数:
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
关键字参数与特殊参数
关键字参数
kwarg=value
形式的 关键字参数 也可以用于调用函数
*name
形参可以与 *name
形参(下一小节介绍)组合使用(*name
必须在 **name
前面), *name
形参接收一个元组,该元组包含形参列表之外的位置参数
def cheeseshop(kind, *arguments, **keywords):
print("kind = ", kind, "!!!!")
for arg in arguments:
print(arg)
print("-" * 40)
for kw in keywords:
print(kw, ":", keywords[kw])
cheeseshop("cpu", "It's very big",
"It's data",
shopkeeper="code",
client="hei",
sketch="liubi")
关键字参数在输出结果中的顺序与调用函数时的顺序一致
特殊参数
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
----------- ---------- ----------
| | |
| Positional or keyword |
| - Keyword only
-- Positional only
/
和 *
是可选的
这些符号表明形参如何把参数值传递给函数:位置、位置或关键字、关键字
关键字形参也叫作命名形参
位置或关键字参数
函数定义中未使用 / 和 * 时,参数可以按位置或关键字传递给函数
仅位置参数
特定形参可以标记为 仅限位置。仅限位置 时,形参的顺序很重要,且这些形参不能用关键字传递
仅限位置形参应放在 /
(正斜杠)前
/
用于在逻辑上分割仅限位置形参与其它形参。如果函数定义中没有 /
,则表示没有仅限位置形参
/
后可以是 位置或关键字 或 仅限关键字 形参
仅限关键字参数
把形参标记为 仅限关键字,表明必须以关键字参数形式传递该形参,应在参数列表中第一个 仅限关键字 形参前添加 *
文件操作
打开文件
open()
方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError
open() 方法一定要保证关闭文件对象,即调用 close() 方
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
- file: 必需,文件路径(相对或者绝对路径)
- mode: 可选,文件打开模式(默认只读)
- buffering: 设置缓冲
- encoding: 一般使用 utf8
- errors: 报错级别
- newline: 区分换行符
- closefd: 传入的 file 参数类型
- opener: 设置自定义开启器,开启器的返回值必须是一个打开的文件描述符
mode 参数 :
模式 | 描述 |
---|---|
t | 文本模式 (默认) |
x | 写模式,新建一个文件,如果该文件已存在则会报错 |
b | 二进制模式 |
+ | 打开一个文件进行更新(可读可写) |
U | 通用换行模式(Python 3 不支持) |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写 |
默认为文本模式,如果要以二进制模式打开,加上 b
file 对象 :
方法 | 描述 |
---|---|
file.close() | 关闭文件。关闭后文件不能再进行读写操作 |
file.flush() | 刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入 |
file.fileno() | 返回一个整型的文件描述符(file descriptor FD 整型)可以用在如 os 模块的 read() 方法等一些底层操作上 |
file.isatty() | 如果文件连接到一个终端设备返回 True ,否则返回 False |
file.next() | Python 3 中的 File 对象不支持 next() 方法。 返回文件下一行 |
file.read(size) | 从文件读取指定的字节数,如果未给定或为负则读取所有 |
file.readline(size) | 读取整行,包括 \n 字符 |
file.readlines(sizeint) | 读取所有行并返回列表,若给定 sizeint > 0 ,返回总和大约为 sizeint 字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区 |
file.seek(offset, whence) | 移动文件读取指针到指定位置 |
file.tell() | 返回文件当前位置 |
file.truncate(size) | 从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,其中 Windows 系统下的换行代表 2 个字符大小 |
file.write(str) | 将字符串写入文件,返回的是写入的字符长度 |
file.writelines(sequence) | 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符 |
文件的读写
write 写数据
write()
方法用于向文件中写入指定字符串
在文件关闭前或缓冲区刷新前,字符串内容存储在缓冲区中,这时你在文件中是看不到写入的内容
with open('demo.txt', 'w') as f:
length = f.write("cpucode")
print(length)
如果文件不存在那么创建,如果存在那么就先清空,然后写入数据
read 读数据
read()
方法用于从文件读取指定的字节数,如果未给定或为负则读取所有
with open('demo.txt', 'w') as f:
f.write("cpuCode")
with open('demo.txt','r') as f:
content = f.read()
print(content)
向文件里写入列表
给定一个文件路径 path,一个列表 list_1,向文件里写入这个列表
def write_list(path: str, list_1: list):
with open(path, 'w') as f:
f.write(str(list_1))
f.close()
readlines 读数据
readlines : 按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素
f = open('text.txt', 'r')
content = f.readlines()
print(type(context))
i = 1
for temp in content:
print('%d : %s' % (i, temp))
i += 1
f.close()
readline 读数据
f = open('text.txt', 'r')
content = f.readline()
print('1: %s' % context)
context = f.readline()
print('2: %s' % content)
f.close()
读写 JSON 文件
JSON 在 Python 中分别由 list
和 dict
组成
json 模块提供了四个功能:
- dumps : 把数据类型转换成字符串
- dump : 把数据类型转换成字符串并存储在文件中
- loads : 把字符串转换成数据类型
- load : 把文件打开从字符串转换成数据类型
写入 JSON 文件
json 模块提供了一个名为 dump() 的方法,将 Python 对象转换为适当的 JSON 对象
dump()
和 dumps()
的区别
dump() | dumps() |
---|---|
当 Python 对象必须被存储在一个文件中时,dump() 方法就会被使用 | dumps() 是在要求对象为字符串格式时使用的,用于解析、打印等 |
dump() 需要将输出的 JSON 文件名作为一个参数来存储 | dumps() 并不要求传递任何这样的文件名 |
这种方法在内存中写入,然后单独执行写入磁盘的命令 | 这个方法直接写到 JSON 文件中 |
较快的方法 | 慢 2 倍 |
json.dump(d, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None)
-
indent:它提高了 JSON 文件的可读性。可以传递给这个参数的可能值是简单的双引号(""),任何整数值。简单的双引号使每个键值对出现在新的一行
-
skipkeys:如果键不属于标准允许的类型,如 int,float,string,None 或 bool,在转储它们时将产生错误
-
separator:这个参数有一个或两个值。第一个值指定将一个键值对与另一个键值对分开的符号。下一个值指定将值和它的键分开的符号
-
sort_keys:这个参数采用布尔值。如果它被设置为 True,键将以升序设置,否则,它们将以 Python 对象的形式出现
-
ensure_ascii:这个参数也只取布尔值。如果它没有被设置为 True,非 ASCII 字符将被原封不动地转入输出文件。默认情况下,该值为 True
-
allow_nan:它有助于序列化浮点数的范围
将一个 data 字典写入 demo.json 文件 :
# 写入 JSON 数据
import json
data = {
'name': 'cpu',
'age': 8
}
with open('demo.json', 'w') as f:
json.dump(data, f)
读取 JSON 文件
json.loads()
方法可用于解析有效的 JSON 字符串并将其转换为 Python 字典
读取 demo.json 的中的内容 :
# 写入 JSON 数据
import json
data = {
'name': 'cpu',
'age': 8
}
with open('demo.json', 'w') as f:
json.dump(data, f)
# 读取文件
# load() 方法
with open('demo.json', 'r') as f:
print(json.load(f))
# loads() 方法
with open('demo.json', 'r') as f:
print(json.loads(f.read()))
从文件中读取字典并修改它
给定一个文件路径 path,文件格式为 json,将文件里的数据转换为字典,并修改其中 age 属性,将其改成 18,然后将修改后的字典写回文件里
import json
def get_write_dict(path:str):
# Please write your code
with open(path, 'r') as f:
dic = json.load(f)
dic['age'] = 18
f.close()
with open(path,'w') as f:
json.dump(dic, f)
f.close()
读写 CSV 文件
CSV (逗号分隔值)是一种简单的文件格式,用于存储表格数据,如 : 电子表格或数据库
CSV 文件以纯文本形式存储表格数据(数字和文本)
文件的每一行都是一条数据记录。每条记录由一个或多个字段组成,以逗号分隔
写入 CSV 文件
内置库 csv,生成一个 csvwriter 对象,可以一行一行写入,也可以一次写入多行
import csv
fields = ['Name', 'Branch', 'Year', 'CGPA']
rows = [ ['Nikhil', 'COE', '2', '9.0'],
['Sanchit', 'COE', '2', '9.1'],
['Aditya', 'IT', '2', '9.3'],
['Sagar', 'SE', '1', '9.5'],
['Prateek', 'MCE', '3', '7.8'],
['Sahil', 'EP', '2', '9.1']]
# writing to csv file
with open('demo.csv', 'w') as csvfile:
# 创建一个 csv writer 对象
csvwriter = csv.writer(csvfile)
# 一次写一行
csvwriter.writerow(fields)
# 一次写入多行
csvwriter.writerows(rows)
读取 CSV 文件
csv 内置库,生成一个 csvreader 对象
import csv
fields = ['Name', 'Branch', 'Year', 'CGPA']
rows = [ ['Nikhil', 'COE', '2', '9.0'],
['Sanchit', 'COE', '2', '9.1'],
['Aditya', 'IT', '2', '9.3'],
['Sagar', 'SE', '1', '9.5'],
['Prateek', 'MCE', '3', '7.8'],
['Sahil', 'EP', '2', '9.1']]
with open('demo.csv', 'w') as csvfile:
# 创建一个 csv writer 对象
csvwriter = csv.writer(csvfile)
# 一次写一行
csvwriter.writerow(fields)
# 一次写入多行
csvwriter.writerows(rows)
with open('demo.csv', 'r') as csvfile:
csvreader=csv.reader(csvfile)
print(list(csvreader))
读取 csv 文件并修改
一个 csv 文件路径 path,读取 csv 文件内容,然后将第一行的 ‘name’ 修改成 ‘student_name’,然后将修改后的内容写回 path 中
import csv
def get_write_csv(path:str):
# Please write your code
with open(path, 'r') as f:
lines = f.readlines()
lines[0] = lines[0].replace('name', 'student_name')
with open(path, 'w') as f:
f.writelines(lines)
f.close()
读写二进制文件
二进制文件(英语:Binary file)一般指包含 ASCII 及扩展 ASCII 字符中编写的数据或程序指令(Program instructions)的文件
广义的二进制文件 : 为文件,由文件在外部存储设备的存放方式为二进制
狭义的二进制文件 : 除文本文件以外的文件
写入二进制文件
将一个字节序列的 data 写入 demo.pdf 文件中
data = b'1'
with open('demo.pdf', 'wb') as f:
f.write(data)
读取二进制文件
指定 open 函数的 mode 参数为 rb 就可以写入二进制文件,这里的 r 表示 read 读取,b 表示 binary 二进制模式
写入到 demo.pdf 中的 data,并打印
data = b'1'
with open('demo.pdf', 'wb') as f:
f.write(data)
with open('demo.pdf','rb') as f:
data = f.read()
print(data, type(data))
二进制文件和文本文件的区别
- 文本文件:是基于字符编码的文件,常见的编码有 ASCII 编码,UNICODE 编码
- 二进制文件:是基于值编码的文件,你可以根据具体应用,指定某个值是什么意思
文本文件与二进制文件的存取
- 二进制文件 : 把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放 ( 数据的原形式 )
- 文本文件 : 把数据的终端形式的二进制数据输出到磁盘上存放 ( 数据的终端形式 )
文本文件与二进制文件的优缺点
文件的相关操作
os 模块
方法 | 说明 |
---|---|
os.access(path, mode) | 检验权限模式 |
os.chdir(path) | 改变当前工作目录 |
os.chflags(path, flags) | 设置路径的标记为数字标记 |
os.chmod(path, mode) | 更改权限 |
os.chown(path, uid, gid) | 更改文件所有者 |
os.chroot(path) | 改变当前进程的根目录 |
os.close(fd) | 关闭文件描述符 fd |
os.closerange(fd_low, fd_high) | 关闭所有文件描述符,从 fd_low (包含)到 fd_high (不包含),错误会忽略 |
os.dup(fd) | 复制文件描述符 fd |
os.dup2(fd, fd2) | 将一个文件描述符 fd 复制到另一个 fd2 |
os.fchdir(fd) | 通过文件描述符改变当前工作目录 |
os.fchmod(fd, mode) | 改变一个文件的访问权限,该文件由参数 fd 指定,参数 mode 是Unix 下的文件访问权限 |
os.fchown(fd, uid, gid) | 修改一个文件的所有权,这个函数修改一个文件的用户 ID 和用户组 ID,该文件由文件描述符 fd 指定 |
os.fdatasync(fd) | 强制将文件写入磁盘,该文件由文件描述符 fd 指定,但是不强制更新文件的状态信息 |
os.fdopen(fd[, mode[, bufsize]]) | 通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 |
os.fpathconf(fd, name) | 返回一个打开的文件的系统配置信息。name 为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它) |
os.fstat(fd) | 返回文件描述符 fd 的状态,像 stat() |
os.fstatvfs(fd) | 返回包含文件描述符 fd 的文件的文件系统的信息,Python 3.3 相等于 statvfs() |
os.fsync(fd) | 强制将文件描述符为 fd 的文件写入硬盘 |
os.ftruncate(fd, length) | 裁剪文件描述符 fd 对应的文件,所以它最大不能超过文件大小 |
os.getcwd() | 返回当前工作目录 |
os.getcwdb() | 返回一个当前工作目录的 Unicode 对象 |
os.isatty(fd) | 如果文件描述符 fd 是打开的,同时与 tty(-like) 设备相连,则返回 true ,否则 False |
os.lchflags(path, flags) | 设置路径的标记为数字标记,类似 chflags() ,但是没有软链接 |
os.lchmod(path, mode) | 修改连接文件权限 |
os.lchown(path, uid, gid) | 更改文件所有者,类似 chown ,但是不追踪链接 |
os.link(src, dst) | 创建硬链接,名为参数 dst ,指向参数 src |
os.listdir(path) | 返回 path 指定的文件夹包含的文件或文件夹的名字的列表 |
os.lseek(fd, pos, how) | 设置文件描述符 fd 当前位置为 pos ,how 方式修改: SEEK_SET 或者 0 设置从文件开始的计算的 pos ;SEEK_CUR 或者 1 则从当前位置计算;os.SEEK_END 或者 2 则从文件尾部开始。在 Unix,Windows 中有效 |
os.lstat(path) | 像 stat() ,但是没有软链接 |
os.major(device) | 从原始的设备号中提取设备 major 号码 (使用 stat 中的 st_dev 或者 st_rdev field) |
os.makedev(major, minor) | 以 major 和 minor 设备号组成一个原始设备号 |
os.makedirs(path[, mode]) | 递归文件夹创建函数。像 mkdir() ,但创建的所有 intermediate-level 文件夹需要包含子文件夹 |
os.minor(device) | 从原始的设备号中提取设备 minor 号码(使用 stat 中的 st_dev 或者 st_rdev field ) |
os.mkdir(path[, mode]) | 以数字 mode 的 mode 创建一个名为 path 的文件夹。默认的 mode 是 0777(八进制) |
os.mkfifo(path[, mode]) | 创建命名管道,mode 为数字,默认为 0666(八进制) |
os.mknod(filename[, mode=0600, device]) | 创建一个名为 filename 文件系统节点(文件,设备特别文件或者命名管道) |
os.open(file, flags[, mode]) | 打开一个文件,并且设置需要的打开选项,mode 参数是可选的 |
os.openpty() | 打开一个新的伪终端对。返回 pty 和 tty 的文件描述符 |
os.pathconf(path, name) | 返回相关文件的系统配置信息 |
os.pipe() | 创建一个管道。返回一对文件描述符 (r, w) 分别为读和写 |
os.popen(command[, mode[, bufsize]]) | 从一个 command 打开一个管道 |
os.read(fd, n) | 从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd 对应文件已达到结尾,返回一个空字符串 |
os.readlink(path) | 返回软链接所指向的文件 |
os.remove(path) | 删除路径为 path 的文件。如果 path 是一个文件夹,将抛出 OSError ;查看下面的 rmdir() 删除一个 directory |
os.removedirs(path) | 递归删除目录 |
os.rename(src, dst) | 重命名文件或目录,从 src 到 dst |
os.renames(old, new) | 递归地对目录进行更名,也可以对文件进行更名 |
os.rmdir(path) | 删除 path 指定的空目录,如果目录非空,则抛出一个 OSError 异常 |
os.stat(path) | 获取 path 指定的路径的信息,功能等同于 C API 中的 stat() 系统调用 |
os.stat_float_times([newvalue]) | 决定 stat_result 是否以 float 对象显示时间戳 |
os.statvfs(path) | 获取指定路径的文件系统统计信息 |
os.symlink(src, dst) | 创建一个软链接 |
os.tcgetpgrp(fd) | 返回与终端 fd (一个由 os.open() 返回的打开的文件描述符)关联的进程组 |
os.tcsetpgrp(fd, pg) | 设置与终端 fd (一个由 os.open() 返回的打开的文件描述符)关联的进程组为 pg |
os.ttyname(fd) | 返回一个字符串,它表示与文件描述符 fd 关联的终端设备。如果 fd 没有与终端设备关联,则引发一个异常 |
os.unlink(path) | 删除文件路径 |
os.utime(path, times) | 返回指定的 path 文件的访问和修改的时间 |
os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]]) | 输出在文件夹中的文件名通过在树中游走,向上或者向下 |
os.write(fd, str) | 写入字符串到文件描述符 fd 中。返回实际写入的字符串长度 |
os.path 模块 | 获取文件的属性信息 |
os.pardir() | 获取当前目录的父目录,以字符串形式显示目录名 |
os.path 模块
方法 | 说明 |
---|---|
os.path.abspath(path) | 返回绝对路径 |
os.path.basename(path) | 返回文件名 |
os.path.commonprefix(list) | 返回 list (多个路径)中,所有 path 共有的最长的路径 |
os.path.dirname(path) | 返回文件路径 |
os.path.exists(path) | 路径存在则返回 True ,路径损坏返回 False |
os.path.lexists | 路径存在则返回 True ,路径损坏也返回 True |
os.path.expanduser(path) | 把 path 中包含的 “~” 和 “~user” 转换成用户目录 |
os.path.expandvars(path) | 根据环境变量的值替换 path 中包含的 “
n
a
m
e
"
和
"
name" 和 "
name"和"{name}” |
os.path.getatime(path) | 返回最近访问时间(浮点型秒数) |
os.path.getmtime(path) | 返回最近文件修改时间 |
os.path.getctime(path) | 返回文件 path 创建时间 |
os.path.getsize(path) | 返回文件大小,如果文件不存在就返回错误 |
os.path.isabs(path) | 判断是否为绝对路径 |
os.path.isfile(path) | 判断路径是否为文件 |
os.path.isdir(path) | 判断路径是否为目录 |
os.path.islink(path) | 判断路径是否为链接 |
os.path.ismount(path) | 判断路径是否为挂载点 |
os.path.join(path1[, path2[, ...]]) | 把目录和文件名合成一个路径 |
os.path.normcase(path) | 转换 path 的大小写和斜杠 |
os.path.normpath(path) | 规范 path 字符串形式 |
os.path.realpath(path) | 返回 path 的真实路径 |
os.path.relpath(path[, start]) | 从 start 开始计算相对路径 |
os.path.samefile(path1, path2) | 判断目录或文件是否相同 |
os.path.sameopenfile(fp1, fp2) | 判断 fp1 和 fp2 是否指向同一文件 |
os.path.samestat(stat1, stat2) | 判断 stat tuple stat1 和 stat2 是否指向同一个文件 |
os.path.split(path) | 把路径分割成 dirname 和 basename ,返回一个元组 |
os.path.splitdrive(path) | 一般用在 Windows 下,返回驱动器名和路径组成的元组 |
os.path.splitext(path) | 分割路径中的文件名与拓展名 |
os.path.splitunc(path) | 把路径分割为加载点与文件 |
os.path.walk(path, visit, arg) | 遍历 path ,进入每个目录都调用 visit 函数,visit 函数必须有 3 个参数(arg, dirname, names ),dirname 表示当前目录的目录名,names 代表当前目录下的所有文件名,args 则为 walk 的第三个参数 |
os.path.supports_unicode_filenames | 设置是否支持 Unicode 路径名 |
文件重命名
import os
os.rename('cpu.txt', 'cpuCode.txt')
删除文件
import os
os.remove('cpu.txt')
创建文件夹
import os
os.mkdir('张三')
获取当前目录
import os
os.getcwd()
改变默认目录
import os
os.chdir('../')
获取目录列表
import os
os.listdir("./")
删除文件夹
import os
os.rmdir("text")
面对对象
概述
软件开发思想有两种:
- 面向过程
- 面向对象
对于面向过程的思想: 看重的是开发的步骤和过程
对于面向对象的思想:关心谁帮我做这件事
面向对象的三大特征有:
- 封装性
- 继承性
- 多态性
类和对象
面向对象编程的概念:
- 类
- 对象
类
类是抽象的 , 创建对象的模板 , 两个组成部分:
- 属性
- 行为
类的构成
类(Class) 由3个部分构成
- 类的名称 : 类名
- 类的属性 : 一组数据
- 类的方法 : 允许对进行操作的方法 (行为)
类的抽象
拥有相同 或类似属性和行为的对象都可以抽像出一个类
定义类
class 类名:
方法列表
# 新式类定义形式
class Hero(object):
def info(self):
print("英雄各有见,何必问出处。")
- object 是Python 里所有类的最顶级父类
- 类名 的命名规则按照"大驼峰命名法"
- info 是一个实例方法,第一个参数一般是 self,表示实例对象本身
创建对象
定义的类去创建出一个或多个对象
class Hero(object): # 新式类定义形式
"""info 是一个实例方法,类对象可以调用实例方法,实例方法的第一个参数一定是self"""
def info(self):
"""当对象调用实例方法时,Python会自动将对象本身的引用做为参数,
传递到实例方法的第一个参数self里"""
print(self)
print("self各不同,对象是出处。")
# Hero这个类 实例化了一个对象 taidamier(泰达米尔)
taidamier = Hero()
# 对象调用实例方法info(),执行info()里的代码
# . 表示选择属性或者方法
taidamier.info()
# 打印对象,则默认打印对象在内存的地址,结果等同于info里的print(self)
print(taidamier)
# id(taidamier) 则是内存地址的十进制形式表示
print(id(taidamier))
添加和获取对象的属性
class Hero(object):
"""定义了一个英雄类,可以移动和攻击"""
def move(self):
"""实例方法"""
print("正在前往事发地点...")
def attack(self):
"""实例方法"""
print("发出了一招强力的普通攻击...")
# 实例化了一个英雄对象 泰达米尔
taidamier = Hero()
# 给对象添加属性,以及对应的属性值
taidamier.name = "泰达米尔" # 姓名
taidamier.hp = 2600 # 生命值
taidamier.atk = 450 # 攻击力
taidamier.armor = 200 # 护甲值
# 通过.成员选择运算符,获取对象的属性值
print("英雄 %s 的生命值 :%d" % (taidamier.name, taidamier.hp))
print("英雄 %s 的攻击力 :%d" % (taidamier.name, taidamier.atk))
print("英雄 %s 的护甲值 :%d" % (taidamier.name, taidamier.armor))
# 通过.成员选择运算符,获取对象的实例方法
taidamier.move()
taidamier.attack()
self获取对象属性
_init_()
-
_init_()方法,在创建一个对象时默认被调用,不需要手动调用
-
_init_(self) 中的self参数,会自动把当前的对象引用传递过去
通过一个类,可以创建多个对象,就好比 通过一个模具创建多个实体一样
init(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么__init__(self)中出了self作为第一个形参外还需要2个形参,例如__init__(self, x, y)
class Hero(object):
"""定义了一个英雄类,可以移动和攻击"""
def __init__(self, name, skill, hp, atk, armor):
""" __init__() 方法,用来做变量初始化 或 赋值 操作"""
# 英雄名
self.name = name
# 技能
self.skill = skill
# 生命值:
self.hp = hp
# 攻击力
self.atk = atk
# 护甲值
self.armor = armor
def move(self):
"""实例方法"""
print("%s 正在前往事发地点..." % self.name)
def attack(self):
"""实例方法"""
print("发出了一招强力的%s..." % self.skill)
def info(self):
print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))
# 实例化英雄对象时,参数会传递到对象的__init__()方法里
taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200)
gailun = Hero("盖伦", "大宝剑", 4200, 260, 400)
# print(gailun)
# print(taidamier)
# 不同对象的属性值的单独保存
print(id(taidamier.name))
print(id(gailun.name))
# 同一个类的不同对象,实例方法共享
print(id(taidamier.move()))
print(id(gailun.move()))
- 在类内部获取 属性 和 实例方法,通过self获取
- 在类外部获取 属性 和 实例方法,通过对象名获取
- 一个类有多个对象,每个对象的属性是各自保存的,都有各自独立的地址
- 实例方法是所有对象共享的,只占用一份内存空间。类会通过self来判断是哪个对象调用了实例方法
_str_()
class Hero(object):
"""定义了一个英雄类,可以移动和攻击"""
def __init__(self, name, skill, hp, atk, armor):
""" __init__() 方法,用来做变量初始化 或 赋值 操作"""
# 英雄名
self.name = name # 实例变量
# 技能
self.skill = skill
# 生命值:
self.hp = hp # 实例变量
# 攻击力
self.atk = atk
# 护甲值
self.armor = armor
def move(self):
"""实例方法"""
print("%s 正在前往事发地点..." % self.name)
def attack(self):
"""实例方法"""
print("发出了一招强力的%s..." % self.skill)
# def info(self):
# print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
# print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
# print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))
def __str__(self):
"""
这个方法是一个魔法方法 (Magic Method) ,用来显示信息
该方法需要 return 一个数据,并且只有self一个参数,当在类的外部 print(对象) 则打印这个数据
"""
return "英雄 <%s> 数据: 生命值 %d, 攻击力 %d, 护甲值 %d" % (self.name, self.hp, self.atk, self.armor)
taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200)
gailun = Hero("盖伦", "大宝剑", 4200, 260, 400)
# 如果没有__str__ 则默认打印 对象在内存的地址。
# 当类的实例化对象 拥有 __str__ 方法后,那么打印对象则打印 __str__ 的返回值。
print(taidamier)
print(gailun)
# 查看类的文档说明,也就是类的注释
print(Hero.__doc__)
- _xxxx_()的,那么就有特殊的功能,因此叫做“魔法”方法
- print 输出对象的时候,默认打印对象的内存地址
- 类定义 _str_(self)方法,就打印方法中 return 的数据
- __str__方法通常返回一个字符串,作为这个对象的描述信息
_del_()
-
创建对象后,python 解释器默认调用 _init_() 方法
-
当删除对象时,python解释器会默认调用 _del_() 方法
class Hero(object):
# 初始化方法
# 创建完对象后会自动被调用
def __init__(self, name):
print('__init__方法被调用')
self.name = name
# 当对象被删除时,会自动被调用
def __del__(self):
print("__del__方法被调用")
print("%s 被 GM 干掉了..." % self.name)
# 创建对象
taidamier = Hero("泰达米尔")
# 删除对象
print("%d 被删除1次" % id(taidamier))
del(taidamier)
print("--" * 10)
gailun = Hero("盖伦")
gailun1 = gailun
gailun2 = gailun
print("%d 被删除1次" % id(gailun))
del(gailun)
print("%d 被删除1次" % id(gailun1))
del(gailun1)
print("%d 被删除1次" % id(gailun2))
del(gailun2)
私有权限
面向对象三大特性:
- 封装
- 继承
- 多态
私有权限:在属性名和方法名加 __
- 类的私有属性 和 私有方法,都不能通过对象直接访问,只在本类内部访问
- 类的私有属性 和 私有方法,都不会被子类继承,子类也无法访问
- 私有属性 和 私有方法 往往用来处理类的内部事情,不通过对象处理,起到安全作用
class Master(object):
def __init__(self):
self.kongfu = "古法煎饼果子配方"
def make_cake(self):
print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
class Prentice(School, Master):
def __init__(self):
self.kongfu = "猫氏煎饼果子配方"
# 私有属性,可以在类内部通过self调用,但不能通过对象访问
self.__money = 10000
# 私有方法,可以在类内部通过self调用,但不能通过对象访问
def __print_info(self):
print(self.kongfu)
print(self.__money)
def make_cake(self):
self.__init__()
print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
def make_old_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_new_cake(self):
School.__init__(self)
School.make_cake(self)
class PrenticePrentice(Prentice):
pass
damao = Prentice()
# 对象不能访问私有权限的属性和方法
# print(damao.__money)
# damao.__print_info()
pp = PrenticePrentice()
# 子类不能继承父类私有权限的属性和方法
print(pp.__money)
pp.__print_info()
- Python 是以属性命名方式来区分,如在属性和方法名前面加了2个下划线
__
,则表明该属性和方法是私有权限,否则为公有权限
修改私有属性的值
- 对象名.属性名 = 数据 ----> 直接修改
- 对象名.方法名() ----> 间接修改
- 私有属性不能直接访问 , 所以不能修改
class Master(object):
def __init__(self):
self.kongfu = "古法煎饼果子配方"
def make_cake(self):
print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
class School(object):
def __init__(self):
self.kongfu = "现代煎饼果子配方"
def make_cake(self):
print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
class Prentice(School, Master):
def __init__(self):
self.kongfu = "猫氏煎饼果子配方"
# 私有属性,可以在类内部通过self调用,但不能通过对象访问
self.__money = 10000
# 现代软件开发中,通常会定义get_xxx()方法和set_xxx()方法来获取和修改私有属性值。
# 返回私有属性的值
def get_money(self):
return self.__money
# 接收参数,修改私有属性的值
def set_money(self, num):
self.__money = num
def make_cake(self):
self.__init__()
print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
def make_old_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_new_cake(self):
School.__init__(self)
School.make_cake(self)
class PrenticePrentice(Prentice):
pass
damao = Prentice()
# 对象不能访问私有权限的属性和方法
# print(damao.__money)
# damao.__print_info()
# 可以通过访问公有方法set_money()来修改私有属性的值
damao.set_money(100)
# 可以通过访问公有方法get_money()来获取私有属性的值
print(damao.get_money())
多态
多态 : 使用父类对象的地方,也可以使用子类对象
- 子类继承父类
- 子类重写父类中的方法
- 通过对象调用这个方法
# 定义父类
class Father:
def cure(self):
print("父亲给病人治病...")
# 定义子类继承父类
class Son(Father):
# 重写父类中的方法
def cure(self):
print("儿子给病人治病...")
# 定义函数,在里面 调用 医生的cure函数
def call_cure(doctor):
# 调用医生治病的方法
doctor.cure()
# 创建父类对象
father = Father()
# 调用函数,把父类对象传递函数
call_cure(father)
# 创建子类对象
son = Son()
# 调用函数,把子类对象传递函数
call_cure(son)
继承
继承描述的是多个类之间的所属关系
通过继承的方式,传递到类B里
类A就是基类 ( 父类 );类B就是派生类 ( 子类 )
# 父类
class A(object):
def __init__(self):
self.num = 10
def print_num(self):
print(self.num + 10)
# 子类
class B(A):
pass
单继承
子类只继承一个父类
# 定义一个Master类
class Master(object)
def __init__(self):
# 属性
self.kongfu = "好配方"
# 实例方法
def make_cake(self):
print("<%s>" % self.kongfu)
# 继承了 Master
class Prentice(Master):
# 可以使用父类的属性和方法
pass
damao = Prentice()
print(damao.kongfu)
damao.make_cake()
-
子类没有定义 _init_ 方法初始化属性,也没有定义实例方法,但是父类有
-
创建子类的对象,默认执行继承的 _init_ 方法
-
子类在继承的时候,在定义类时,小括号()中为父类的名字
-
父类的属性、方法,会被继承给子类
多继承
子类继承多个父类
class Master(object):
def __init__(self):
# 实例变量,属性
self.kongfu = 'cpu'
def make_cake(self):
print('Master 的 self.kongfu = %s' % self.kongfu)
def test1(self):
print('厉害了')
class School(object):
def __init__(self):
self.kongfu = 'code'
def make_cake(self):
print('School 的 self.kongfu = %s' % self.kongfu)
def test2(self):
print('流弊坏了')
# 多继承,继承了多个父类(Master在前)
class Prentice(Master, School):
pass
damao = Prentice()
# 执行Master的属性
print(damao.kongfu)
# 执行Master的实例方法
damao.make_cake()
# 子类的魔法属性__mro__决定了属性和方法的查找顺序
print(Prentice.__mro__)
damao.test1()
damao.test2()
- 多继承可以继承多个父类,也继承了所有父类的属性和方法
- 多个父类中有同名的属性和方法,则默认使用第一个父类的属性和方法
- 多个父类中,不重名的属性和方法 , 不影响
子类重写父类
class Master(object):
def __init__(self):
self.kongfu = 'cpu'
def make_cake(self):
print('Master self.kongfu = %s', % self.kongfu)
class School(object):
def __init__(self):
self.kongfu = "code"
def make_cake(self):
print("School self.kongfu = %s" % self.kongfu)
# 多继承,继承了多个父类
class Prentice(School, Master):
def __init__(self):
self.kongfu = "cpuCode"
def make_cake(self):
print("Prentice self.kongfu = %s" % self.kongfu)
# 子类重写父类的同名方法和属性
damao = Prentice()
print(damao.kongfu)
damao.make_cake()
# 子类的魔法属性__mro__决定了属性和方法的查找顺序
print(Prentice.__mro__)
子类调用父类
class Master(object):
def __init__(self):
# 实例变量,属性
self.kongfu = 'cpu'
# 实例方法,方法
def make_cake(self):
class School(object):
def __init__(self):
# 实例变量,属性
self.kongfu = 'code'
def make_cake(self):
print("School self.kongfu = %s" % self.kongfu)
# 多继承,继承了多个父类
class Prentice(School, Master):
def __init__(self):
self.kongfu = "cpuCode"
def make_cake(self):
# 实例化对象,自动执行子类的__init__方法
damao = Prentice()
# 调用子类的方法
damao.make_cake()
print("--" * 10)
# 进入实例方法去调用父类Master
damao.make_old_cake()
多层继承
class Master(object):
def __init__(self):
self.kongfu = "cpu"
def make_cake(self):
print("Master self.kongfu = %s " % self.kongfu)
class School(object):
def __init__(self):
self.kongfu = "code"
def make_cake(self):
print("School self.kongfu = %s" % self.kongfu)
# 多继承,继承了多个父类
class Prentice(School, Master):
def __init__(self):
self.kongfu = "cpuCode"
self.money = 10000
def make_cake(self):
# 执行本类的__init__方法
self.__init__()
print("self.kongfu = %s" % self.kongfu)
# 调用父类方法格式:父类类名.父类方法(self)
def make_old_cake(self):
# 调用了父类Master的__init__方法
Master.__init__(self)
# 调用了父类Master的实例方法
Master.make_cake(self)
def make_new_cake(self):
# 调用了父类School的__init__方法
School.__init__(self)
# 调用父类School的实例方法
School.make_cake(self)
# 多层继承
class PrenticePrentice(Prentice):
pass
pp = PrenticePrentice()
# 调用父类的实例方法
pp.make_cake()
pp.make_new_cake()
pp.make_old_cake()
print(pp.money)
super()
class Master(object):
def __init__(self):
# 实例变量,属性
self.kongfu = "cpu"
# 实例方法,方法
def make_cake(self):
print("Master self.kongfu = %s" % self.kongfu)
# 父类是 Master类
class School(Master):
def __init__(self):
# 多继承,继承了多个父类
class Prentice(School, Master):
def __init__(self):
damao = Prentice()
damao.make_cake()
damao.make_all_cake()
- 子类继承了多个父类,如果父类类名修改了,那么子类也要涉及多次修改
- 使用super() 可以逐一调用所有的父类方法,并且只执行一次
- 继承了多个父类,且父类都有同名方法,则默认只执行第一个父类
异常
异常 : 当 Python 检测到错误时,解释器无法执行 , 出现错误的提示
常见的异常
除零错误
1/0
ZeroDivisionError: division by zero
数组越界错误
a = [1, 2, 3]
print(a[3])
IndexError: list index out of range
运算符错误
a = 123
b = '123'
print(a + b)
TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’
捕获异常
捕获异常 try…except…
try:
1/0
except Exception as error:
print('发生如下错误:',error)
- 执行 try 子句(在关键字 try 和关键字 except 之间的语句)
- 没有异常发生,忽略 except 子句,try 子句执行后结束
- 执行 try 子句的过程中发生异常,那么 try 子句余下的部分将被忽略
- 一个异常没有与任何的 except 匹配,那么异常将会传递给上层的 try 中
except捕获多个异常
try:
print('-----test--1---')
open('123.txt','r') # 如果123.txt文件不存在,那么会产生 IOError 异常
print('-----test--2---')
print(num)# 如果num变量没有定义,那么会产生 NameError 异常
except (IOError,NameError):
#如果想通过一次except捕获到多个异常可以用一个元组的方式
- 当捕获多个异常时,可以把要捕获的异常的名字,放到 except 后,只进行元组存储
获取异常的信息描述
捕获所有异常
else
try:
num = 100
print(num)
except NameError as errorMsg:
print('产生错误了: %s' % errorMsg)
else:
print('没有捕获到异常,真高兴')
在 try...except...
没有捕获到异常,就执行 else
try…finally…
finally 必须要执行
try:
1/1
except:
print('出错了')
else:
print('没有出错了')
finally:
print('不管有没有出错,我100%会执行')
阻止黑名单上的人
给定一个黑名单列表 blacklist 和一个顾客列表 customers
class DiscoverBlacklist(Exception):
pass
def selection(blacklist: list, customers: list):
# please write your code here
for customer in customers:
if customer in blacklist:
raise DiscoverBlacklist(f'{customer} 在黑名单里')
return ('全部通过')
内置异常
所有异常必须为一个派生自 BaseException 的类的实例
内置异常的类层级结构 :
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
异常的基类
BaseException
所有内置异常的基类
Exception
所有内置的非系统退出类异常都派生自此类。所有用户自定义异常也应当派生自此类
ArithmeticError
此基类用于派生针对各种算术类错误而引发的内置异常: OverflowError
, ZeroDivisionError
, FloatingPointError
BufferError
当与缓冲区相关的操作无法执行时将被引发
LookupError
基类用于派生当映射或序列所使用的键或索引无效时引发的异常: IndexError, KeyError
这也通过 codecs.lookup() 来直接引发
具体异常
OS 异常
异常均为 OSError 的子类,根据系统错误代码被引发 :
警告
异常被用作警告类别:
Warning
警告类别的基类
UserWarning
用户代码所产生警告的基类
DeprecationWarning
发出的警告是针对其他 Python 开发者的,告知已弃用特性相关警告的基类
PendingDeprecationWarning
已过时并预计在未来弃用,但目前尚未弃用的特性相关警告的基类
SyntaxWarning
与模糊的语法相关的警告的基类
RuntimeWarning
与模糊的运行时行为相关的警告的基类
FutureWarning
发出的警告是针对以 Python 所编写应用的最终用户的,告知已弃用特性相关警告的基类
ImportWarning
与在模块导入中可能的错误相关的警告的基类
UnicodeWarning
与 Unicode 相关的警告的基类
BytesWarning
与 bytes 和 bytearray 相关的警告的基类
ResourceWarning
与资源使用相关的警告的基类。会被默认的警告过滤器忽略
自定义异常
创建一个新的异常类来拥有自己的异常 , 异常类继承自 Exception 类,可以直接继承,或者间接继承
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
try:
raise MyError(2 * 2)
except MyError as e:
print('错误代码 : ', e.value)
raise MyError('oops!')
打印学生平均成绩(异常版)
# Please define the exception here
class KeywordNotFound(Exception):
def __str__(self):
return 'Incomplete keywords'
class NotAllNumbers(Exception):
def __str__(self):
return "It's not all about numbers"
def print_avg(*args, **kwargs) -> str:
try:
if 'student_name' not in kwargs or 'student_age' not in kwargs:
raise KeywordNotFound
else:
for i in args:
if type(i) != type(1):
raise NotAllNumbers
except(KeywordNotFound, NotAllNumbers) as result:
return (result)
else:
name = kwargs["student_name"]
age = kwargs["student_age"]
avg = sum(args) / len(args)
return f"name: {name}, age: {age}, avg: {avg:.2f}"
异常的传递
try嵌套中
import time
try:
f = open('test.txt')
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
finally:
f.close()
print('关闭文件')
except:
print("没有这个文件")
函数嵌套调用中
def test1():
print("----test1-1----")
print(num)
print("----test1-2----")
def test2():
print("----test2-1----")
test1()
print("----test2-2----")
def test3():
try:
print("----test3-1----")
test1()
print("----test3-2----")
except Exception as result:
print("捕获到了异常,信息是:%s"%result)
print("----test3-2----")
test3()
print("------华丽的分割线-----")
test2()
模块
模块概述
Python中的模块
模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块
如 Python 中要调用 sqrt 函数,必须用 import 关键字引入 math 这个模块
import
关键字 import 来引入某个模块
import module1,mudule2...
当两个模块中含有相同名称函数的时候,后面一次引入会覆盖前一次引入
一次性引入 math 中所有的东西,还通过from math import *
来实现
from…import
from 语句让你从模块中导入一个指定的部分到当前命名空间中
要导入模块 fib 的 fibonacci 函数
from fib import fibonacci
from … import *
把一个模块的所有内容全都导入到当前的命名空间
from modname import *
定位模块
导入一个模块,Python解析器对模块位置的搜索顺序是:
- 当前目录
- 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录
- 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为
/usr/local/lib/python/
- 模块搜索路径存储在 system 模块的
sys.path
变量中
模块制作
模块中的 __all__
- 有 __all__变量,这个变量中的元素,会被
from xxx import *
时导入 , 没有在这个变量中的不会被导入
python中的包
引入包
- 将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为_init_.py 文件,那么这个文件夹就称之为包
- 有效避免模块名称冲突问题,让应用组织结构更加清晰
编码规范
- 缩进使用 4 个空格, 空格是首选的缩进方式
- 每一行最大长度限制在 79 个字符以内
- 顶层函数、类的定义, 前后使用两个空行隔开
- 导入建议在不同的行
- 导包位于文件顶部, 在模块注释、文档字符串之后, 全局变量、常量之前
- Python 中定义字符串使用双引号、单引号是相同的, 尽量保持使用同一方式定义字符串
- 避免在小括号、方括号、花括号前跟空格
- 避免在逗号、分好、冒号之前添加空格
- 冒号在切片中就像二元运算符, 两边要有相同数量的空格
- 避免为了和另外一个赋值语句对齐, 在赋值运算符附加多个空格
- 避免在表达式尾部添加空格
- 在二元运算符两边加一个空格
- 避免将小的代码块和 if/for/while 放在同一行
- 永远不要使用字母
l
(小写的L
) ,O
(大写的O
) , 或I
(大写的I
) 作为单字符变量名 - 类名一般使用首字母大写的约定
- 函数名应该小写 , 如果想提高可读性可以用下划线分隔
- 函数的参数名和已有的关键词冲突, 在最后加单一下划线
- 方法名和实例变量使用下划线分割的小写单词
Python 自动化
自动修改 hosts
"""
@dauthor : cpucode
@date : 2022/3/4 13:53
@github : https://github.com/CPU-Code
@csdn : https://blog.csdn.net/qq_44226094
"""
# !/usr/bin/python
# coding:utf8
# hosts文件绝对路径
hostsFile = "./etc/hosts"
def open_file(ip_dict):
Line = []
# 打开文件
fd = open(hostsFile, encoding='utf-8').readlines()
# 用 for 循环列出每一行
for line in fd:
if line.strip() == '':
# 如果是空行也加入列表中,保证文件内容与原内容形式一致
Line.append(line)
else:
# 取得 hosts 文件中的 ip 地址
ip_name = line.strip().split()[1]
if ip_name in ip_dict.keys():
Line.append("")
else:
Line.append(line)
else:
for h_ip in ip_dict.keys():
Line.append(ip_dict[h_ip])
Line.append(' ')
Line.append(h_ip)
Line.append('\n')
return Line
def write_file(lineText):
# 重新把列表的内容写入到/etc/hosts文件中
fc = open(hostsFile, 'w', encoding='utf-8')
fc.writelines(lineText)
fc.close()
def ips_dict(ips):
ipsName = []
ips_len = len(ips)
for i in range(ips_len):
name = 'cpu'
num = 101 + i
ipsName.append(name + str(num))
return dict(zip(ipsName, ips))
if __name__ == '__main__':
ips = ['172.18.40.114', '172.18.40.115', '172.18.40.116']
ipsDictName = ips_dict(ips)
lineText = open_file(ipsDictName)
write_file(lineText)