Python基础知识(一)
python注释语法
# 注释是代码之母
1.注视就是对代码的解释,不参与程序的运行
2.如何使用注释
方式1:使用#
方式2:多行注释 '''多行注释'''
方式3:快捷键 control+?
代码规范
PEP8规范
变量
# 什么是变量?
即为变化的量,用于记录事务的某种状态
# 如何使用变量
日常生活中:
姓名:alan
年龄:18
爱好:学习
程序中:
username = "alan"
age = 18
hobby = "learn"
语法格式
变量名 赋值符号 变量值
复制顺序:从右往左读取
底层原理(内存中)***
1.在内存空间中申请一块内存空间 存储 数据
2.将18所在的内存空间地址绑定给变量名
3.之后如果访问数据 就通过变量名访问即可
# 命名规范
1.变量名只能由数字、字母、下划线任意组合
2.不能以数字开头,尽量不要用下划线开头(下划线有特殊含义)
3.变量名不能跟关键字冲突
4.变量名的命名一定要做到见名知意
# 命名风格
1.驼峰体 JavaScript推荐使用
大驼峰
UserNameFormDb
小驼峰
userNameFormDb
2.下划线 python推荐使用
user_name_from_db
# 变量三要素
1.变量的值value
2.变量的内存地址 print(id(name)) 一串数字相当于内存地址编号
3.变量的类型 print(type(name))
常量
# 主要用于记录一些不变的状态
在python中没有真正意义上的常量 墨守成规的将全大写的变量看成常量,在其他编程语言中,定义了常量之后就不能修改了
HOST = "127.0.0.1"
# 一般在配置文件中用的比较多
python底层优化
小整数池:
0-255
python解释器有、pycharm中也有
同一个内存空间由多个变量名指向;但是一个变量名只能指向一个内存地址
===》当数据很小的时候,就会进行优化,数据大的时候就不行了
垃圾回收机制
# 垃圾的定义
没有变量名指向的数据称之为垃圾
# 针对垃圾数据,python开发了一套自动化回收方案
1.引用计数
引用:
计数:
===》内存上数据所在的内存地址被引用的次数
2.标记清除
当内存即将占满的时候,python回自动暂停程序的执行 从头到尾将内存中数据进行扫描
并打上标记 之后一次性清除掉标记的数据
3.分代回收
通常有三代:青春代、中年代、老年代
将数据的监管分为三个层次,随着层级的下降监督的频率降低
数据类型
# 什么是数据类型
在现实生活中存储数据的方式和表现形式
文本文件、表格文件、视频文件、音频文件、图片文件。。。
在程序中存储数据的方式和表现形式
int、float、str、dict、list、set、bool、class、function
# 整形 int
age = 18
类型转换:
res = '123' ===> res = int(res) # 只能转化纯数字(整数)
进制数转换
bin(100) # 将十进制的100转为二进制 0b1100100 int("0b1100100", 2) <=> 100
oct(100) # 将十进制的100转为八进制 0o144 int("0o144", 8) <=> 100
hex(100) # 将十进制的100转为十六进制 0x64 int("0x64", 16) <=> 100
# 浮点型 float
prince = 99.9
类型转换
res = '123.123' ===> res = float(res)
===》"""整形和浮点型统称为数字类型"""
# 字符串 str
name = "alan"
定义方式:
单引号、双引号、三引号(单三引、双三引)
内置方法:
类型转换
str(res) # res可以为任意类型数据
索引取值
res[0]
切片操作
res[1: 4] # 顾头不顾尾
res[1: 10: 2] # 顾头不顾尾,第三个参数为步长
支持负数
res[::-1] # 取反 改变取值方向
统计字符串内的字符个数
len(res)
成员运算
移除字符串首尾特定字符
res.strip() # 如果不指定字符,默认移除首尾空格
lstrip() # 右移
rstrip() # 左移
按照指定的字符切割字符
res.split("|") # 该方法的结果是一个列表
res.split("|", maxsplit=1) # maxsplit用于控制切割次数
res.lsplit("|") # 右切
res.rsplit("|") # 左切
字母全小写、字母全大写
lower()、upper()
'''实际案例:图片验证码忽略大小写'''
isupper() # 判断是否为全大写
islower() # 判断是否为全小写
判断字符串是否以指定的字符开头、以什么什么结尾
res.startswith("alan")
res.endswith("18")
格式化输出format
res = 'my name in {}'
res.format("alan")
res = 'my name in {0},{0}'
res.format("alan") # 大括号内写索引值,打破顺序,并且可以反复使用相同位置的数据
res = 'my name in {name},{age}'
res.format(name="alan",age=18) # 大括号内可以指名道姓的要
字符串的拼接
方式一:字符串相加
方式二:join方法
l = ["alan", "tom"]
"l".join(l) # 注意l必须全为字符串类型数据
替换字符串中指定字符replace
res.replace("__old: str", "__new: str", count=num) # 第三个参数默认全选
判断字符串中是否纯数字isdigit
res.isdigit()
字体格式相关
res.title() # 所有英语单词首字母大写
res.capitalize() # 开头英语单词大写
res.swapcase() # 大小写转换
查找索引
res.find("alan") # 从左往右,查找指定字符索引值("a"),找到一个即结束,找不到返回-1
res.index("w") # 找不到会报错
统计某个字符出现的次数
res.count("alan")
填充相关
res.center(15, "$") # 将res居中展示,并且用指定字符填充
res.ljust(15, "$") # 左对齐
res.rjust(15, "$") # 左对齐
判断字符串中既可以包含数字也可以包含字母
isalnum()
判断字符串中只包含字母
isalpha()
# 列表 list
names_list = ["alan", "tom", "pake"]
特点:列表中通常存放相同类型的数据
作用:能够存储多个数据,数据可以为任意类型的数据,并方便取出存储的数据
索引取值:name_lists[0] ===》 "alan"
内置方法:
类型转换:
list(res) # res要是一个可迭代的数据,数字类型不行
索引取值
res[0]
切片操作
res[1: 9: 2] # 得到一个子列表,遵循顾头不顾尾
统计列表中元素的个数
len(res)
修改值
res[0] = 666
添加值
res[4] = 777 # 当索引不存在时,会报错,不能这么添加
方式一:尾部追加,将括号内的数据当成一个整体追加到列表末尾
res.append(666)
方式二:索引插入,同尾部追加一样,也是整体插入到指定位置
res.insert(__index:int, __object:T)
方式三:列表合并(扩展)
res.extend([666, 777]),底层就是for+append
删除值
方式一:通用删除方式,根据索引执行删除
del res[0]
方式二:括号内指定需要移除的元素
res.remove(__value:T) # 没有返回值,None
方式三:pop()括号内可以指定需要弹出的元素索引值,默认弹出末尾元素
res.pop() # 存在返回值,拿到被删除的值
排序
res.sort(reverse=False) # 默认升序False
res.reverse() # 翻转、顺序颠倒 <=> res[::-1] # 后者可以作为深拷贝res[:]
比较运算
按照索引依次比较,看带头大哥(a-z:,A-Z:65-90)
深浅拷贝
copy
deepcopy
# 字典 dict
user_info = {"name": "alan", "age": 18, "hobby": "learn"}
作用:精确地存储数据,知道存储的数据表示什么意思
特点:K通常为字符串,起到描述V的作用,为不可变类型,且K不能重复,重复则保留最新的那个
基于哈希,不能索引取值,需要使用K
内置方法:
类型转换
dict("name"='alan')
dict([['name', 'alan'],['age', 18]])
dict({"name": "alan"})
按K取值 res["name"]
K不存在,则直接报错,不推荐使用 # 用get避免不存在的情况
按K修改值 res["name"] = 'alan'
K存在修改值,不存在则创建键值对
统计字典内部键值对的对数
len(res)
成员运算 针对的是K
"alan" in res False
"name" in res True
删除元素
方式一:
del res['name']
方式二:
res.pop(self, key) # 必须要有参数,为key;存在返回值,弹出Value
方式三:
res.popitem(self) # 弹出一组键值对,使用频率较低
get取值
不同于按K取值,当K不存在时,返回None;也可以利用第二个参数,自定义K不存在的返回值
keys、values、items
res.keys() # 返回字典所有的key,dict_keys([]) 类似于列表,python3进行了优化,类似于range()
res.values() # 返回字典所有的value,看成列表
res.items() # 返回字典所有的键值对 看成列表套元组的形式,元组内两个元素,第一个为键,第二个为值
更新字典updata
res.updata(new_dict)
key存在修改,不存在则创建
初始化字典fromkeys
dict.formkeys(["k1", "k2"], [])
dict.formkeys(range(5)) # {0: None, 1: None...}
setdefault
键存在不修改,获取key对应的值
键不存在新增,并返回修改后的值
res.setdefault("name", 'alan')
# 布尔值 bool
作用:用于判断事务的对错 是否可行
定义:布尔值只有两种状态,python中都是大写
True
False 0, None, "", [], {}... 对应为False
ps:针对布尔值的变量名,一般采用is开头
# 元组 tuple
作用类比于列表(可以看成不可变的列表)
t = (11 ,22, 33, 44, 55)
元素不支持修改,若元素为可变类型数据,则可以修改
内置方法:
单个元素的元组定义,或者空元组
res = tuple()
res = (1, )
类型转换
res = tuple(itable) # 括号内要为可迭代对象
索引取值
支持负数
切片操作
res[1: 5: 2]
成员运算
统计元组内元素的个数
len(res)
for循环
count计数
# 集合 set
作用:去重和关系运算
s = {11, 22, 33, 44}
定义空集合:
res = set()
特点:集合内的元素是无序的
内置方法:
类型转换
res = set(ret) # ret为可迭代对象,且里面的元素为不可变类型数据
去重
关系运算
本质就是集合的交并补运算
eg:
friend1 = set()
friend2 = set()
friend1 & friend2
friend1 | friend2
friend1 - friend2 # 用户一独有的好友
friend1 ^ friend2 # 并集➖交集后的集合
可变类型与不可变类型
# 查看内存地址的方法:id()
可变类型:列表、字典、集合
值改变 内存地址不变 修改的是原值
不可变类型:字符串、数字类型、元组
值改变 内存地址肯定变 本质就是产生了新值,重新赋值了
队列与堆栈
队列:FIFO
先进先出
堆栈:FILO
先进后出
与用户交互
- 输入
input('请输入您的用户名>>>:')input获取的输入信息全都转换为字符串
- 输出
print()print参数默认后面有个"\n",可以用end修改:print(123, end="\n")
格式化输出
# 定义:
将字符串中的某些内容替换掉再输出,就是格式化输出
# 使用
占位符
%s:可以给任意数据占位
%d:只能给数字占位 print('%08d' %123) # 00000123
format( )
res = "名字为{},年龄为{}"
print(res.format('alan', 18))
运算符
算术运算符:
+-*/ 加减乘除
** 幂运算
% 取余
// 取整
比较运算符:
== # 判断值是否相等
!= # 值不等于
is # 判断内存地址是否相等
赋值运算符
赋值
=
增量赋值
n += 1 <=> n = n + 1 # +=、-=、*=、/=
链式赋值
x = y = z = 666
交叉赋值
m = 1
n = 2
m, n = n, m
解压赋值
names_list = ["alan", "tom"]
user_1, user_2 = names_list # 注意事项:左右两侧个数要对应上
user_1, *_ = names_list # *可以接受多余的元素,赋值给后面的变量名
逻辑运算符
定义:与或非
and、or、not
优先级:
not > and > or
成员运算
定义:
判断某个个体是否在某个群体中
关键词:in、not in
返回的是bool值
身份运算
定义:
判断两个数据 值和内存地址是否相等
流程控制
# 流程控制即控制事务的执行流程
任何使用执行流程的结构可以分为三种
1.顺序结构
自上而下依次运行
2.分支结构
在运行过程中根据条件不同可能会执行不同的流程
3.循环结构
在运行过程有些代码需要反复执行
# 分支结构
关键字:if
'''
if 条件1:
条件成立之后执行的子代码块
elif 条件2:
条件成立之后执行的子代码块
else:
其他
1.条件都会转化为布尔值 从而决定子代码是否执行
2.在python中 使用缩进来表示代码的从属关系
3.并不是所有别的代码都可以拥有子代码
4.同属于某个代码的多行子代码 必须保持相同的缩进量 python默认4个空格
'''
嵌套:
if a > 1:
if a < 100:
print("合法")
# 循环结构
while循环
条件
break:结束本层循环
continue:结束本次循环,eg:打印0-10的数字,但是需要跳过6
标志位的使用:将条件换为flag,直接控制标志位进而控制多层循环
while + else:
while循环正常结束下,会走else里的子代码;当break结束循环下,不会执行else里的子代码
死循环
for循环
遍历取值
for循环字典的key
range(6) <=> [0, 1, 2, 3, 4, 5] # 从0开始,顾头不顾尾
range(4, 10) # 从4开始,顾头不顾尾
range(2, 10, 2) # 第三个参数控制步长
ps:range关键字在python2中为列表;在python3中是一个迭代器(节省存储空间),相当于python2中的xrange。
break:结束本层循环
continue:结束本次循环
else:在for循环正常结束的情况下,才会执行
循环嵌套
字符编码
# 字符编码跟文本文件和字符串有关 与视频音频文件等无关
# 什么是字符编码
计算机内部只识别二进制 但是用户在计算机中却能看到各式各样的字符
===》内部记录人类字符和数字对应关系的数据
# 字符编码发展史
一家独大
ASCII码 记录了英文与数字对应的关系 # 八位二进制(一个bys)2^8-1 = 255,实际就用到7位
a-z 97-122
A-Z 65-90
群雄割据
中文
GBK码:
记录了英文、中文、数字的对应关系
对于英文还是使用一个字节,但是对于中文使用2-3个字节 # 2^16 - 1 = 65535,生僻字可以用三个字节
日文
shift_JIS码:
记录了日文、英文与数字的对应关系
韩文
Euc_kr码:
记录了韩文、英文与数字的对应关系
天下归一
目的:
为了实现不同国家的数据交流
万国码(unicode 1994) === 内存中
统一使用两个字符记录字符与数字的对应关系
utf8(万国码的优化) === 存储时
将英文还是用一个字节存储
将中文使用三个字节或者更多字节存储
# 应用
- 解决文件乱码的问题
保持打开与编码时对应的编码规则一致
- 解决python解释器版本不同带来的差异
Python2使用的是ASCII码,Python3使用utf8码
补救措施:
# coding:utf8 文件头
s = u"你好好好" 字符串前带个u
# 编码与解码
编码:
res.encode('utf8') # bytes类型数据,直接看成二进制数据
纯英文、数字 === b'asd123'
解码:
res.decode(utf8) # 解码过程中,需要与编码保持一致
文件操作
# 文件
文件就是操作系统暴露给用户操作硬盘的快捷方式
# 代码操作文件
关键字open()
三步走:
1.利用关键字open打开文件
open('a.txt', "r", encoding='utf8') # 第一个参数为路径(相对路径、绝对路径)、读写模式、字符编码(可选)
2.利用其他方法操作文件
res.read()
3.关闭文件
res.close()
with上下文管理
with open(同上面三个参数)
# 读写模式
r 只读模式(只能看不能改)
路径不存在,直接报错
f.read() # 读取文件内所有内容
f.write() # 报错
w 只写模式(只能写不能看)
文件路径不存在,创建;路径存在会先清空文件内容,再写入内容
a 只追加模式(只能追加)
文件不存在,自动创建;路径存在不会清空文件内容
# 操作模式
t 文本模式
1.默认的模式
r w a >>> rt wt at
2.该模式所有的操作都是以字符串为基本单位
3.该模式必须指定encoding参数
4.该模式只能操作文本文件
b 二进制模式
1.该模式所有操作都是以bytes类型(二进制)基本单位
2.该模式可以操作任意类型文件
3.该模式不需要指定encoding参数
rb wb ab # b不能省略
# 文件操作方法
1.读系列
f.read() # 一次性读取文件内所有内容
'read括号内可以放数字,在t模式下表示字符个数、在b模式下表示字节个数'
f.readline() # 每次读取文件一行内容
f.readlines() # 读取文件所有内容,并组织成列表的形式,每个元素即为一行
r.readable() # 判断当前文件是否具备读的能力
2.写系列
f.write() # 往文件内写入文本内容,必须为str类型数据
f.writelines(["alan", "tom"]) # 将列表多个元素一次性写入文件
f.writable() # 判断文件是否具备写的能力
f.flush() # 直接将内存文件数据刷到硬盘 相当于ctrl + s
优化:
read()方法:
1.一次性读完之后,光标会停留在文件末尾 无法再次读取文件
2.该方法读取大文件的时候 肯呢个会造成内存溢出的情况
逐行读取文件内容:
for line in f:
print(line)
# 文件内光标的移动
f.seek(offset, whence) # offset偏移量(始终以字节为移动单位,支持负数),whence表示模式0,1,2,默认0
0 以文件开头为参考 支持t、b模式
1 以当前所在的位置为参考 只能b模式
2 以文件结尾为参考 只能b模式
f.tell() # 查看文件光标移动的位置
# 向文件写数据的时候,通常有两种方式
覆盖和新建