git add .
git commit -m "备注信息"
git push -u origin master 上传
git pull origin master 把码云上的代码下载到本地
git pull origin master --allow-unrelated-histories解决本地两个文件上传的冲突
git remote add origin IP地址
1.Markdown常用语法
2.博客园使用
3.思维导图制作
4.排bug技巧
1.标题
用 #+空格 实现
…
2.代码块
三个```实现一个代码块
这是单行代码块效果
用一对``实现
3.列表
有序列表
1.跟内容
2.跟内容
…
无序列表
4.链接
[目标地址名称](目的地IP地址)
5.键盘快捷键之缩进
6.图片
7.分割线
—实现分割线
+++实现分割线
***实现分割线
8.字体样式
加粗
**加粗**
倾斜
**
应用场景
1.有层级关系
2.从大范围到具体
思维导图制作工具
XMind
博客发表条件
1.新技术,以自己的观点发表
2.借鉴国外的一些新技术或者新研究
3.自己的笔记,要求自己的笔记成体系
1.根据错误类型推算,错误哪里出的问题,找具体代码重新审核
2.百度搜索或者谷歌搜索
3.stackoverflow
4.建议自己组一个BUG集合,发布到博客上,以便查验和分享
python2: 源码不统一,有重复 (更新维护到2020年)
python3: 源码统一,无重复
python2:python2中print不用,print “内容”
python3:Python3中print必须用括号括起来,print(“内容”)
python2:数字Python2中input得到的为int
python3:python3中input得到的为str
Python是一门动态解释型的强类型定义语言
变量全部用大写命名,就是常量
单行注释
多行注释
“”"
“”"
三个引号,文档注释,描述文件或者函数使用的注释
字符串 str
整形(数字) int
用于比较和计算
python2:除法的时候返回的是整数(向下取整)
python3:除法的时候返回的的小数(浮点数)
布尔值 bool
input —— 输入:python3中input获取到的内容都是字符串
print —— 输出
number = input("请输入您内容:")
print(number)
type
type(需要检测的对象)
单 if
if 条件:
缩进 结果
money = 10
print("从学校出发")
if money >= 10:
print("买个炸鸡")
print("买个啤酒")
print("走啊走")
print("到家了")
二选一 ,if else
if 条件:
缩进 结果
else:
缩进 结果y
if 3>2:
print("这是如果执行了")
else:
print("这是否则执行了")
多选一或不选 if elif elif elif
if 条件:
缩进 结果
elif 条件:
缩进 结果
elif 条件:
缩进 结果
if 1>2:
print("这是A")
elif 1>6:
print("这是B")
elif 1>5:
print("这是C")
elif 1>4:
print("这是D") # 没有符合要求的就不输出结果
多选一 if elif elif else
if 条件:
缩进 结果
elif 条件:
缩进 结果
elif 条件:
缩进 结果
else :
缩进 结果
if 1>2:
print("A")
elif 2>3:
print("B")
elif 5>6:
print("c")
else:
print("D")
if 嵌套
if 条件:
缩进 结果
if 条件:
缩进 结果
score
if score > 500:
if score > 700 :
print("北大清华")
else:
print("随便找一个大学")
else:
print("分不够,不能上大学")
while 条件:
循环体
例如:
while True:
print("Hello World")
# ctrl + C 终止程序
运行上面的代码会陷入死循环,使用while时一定不能陷入死循环,需要加条件,如下代码
flag = True
while flag:
print("循环体代码")
flag = False #把flag改为假
使用while计数输出,输出0-99
count = 0
while count < 100:
print("count")
count += 1 #每次循环进行自增
用于中断循环,通常再满足某种条件时使用,如下,我希望在等于10时终止程序
num = 1
while num < 6:
print(num)
if num == 3:
break
print("结束") #当num=3时,break,并且下面的代码不执行
用于结束本次循环,仅仅跳出本次,例如,输出1-10,但是不输出3
num = 1
while num < 11:
if num == 3:
continue #当代码执行到这里,结束本次循环,后面的代码不执行,表现为不输出3
print(num)
# 如下代码执行结果为456,是因为满足了while的条件,执行了内部的代码,遇到break终止了程序,所以else内代码不执行
i = 11
while i < 15:
print("456")
i += 1
break
else:
print("123")
# 如下代码执行结果为123,因为while条件不满足,内部代码不执行,直接执行else内部的代码
i = 11
while i < 10:
print("456")
i += 1
break
else:
print("123")
# 如下代码的结果为四遍456,一遍123,当执行完while内部代码之后,还会执行else 内部的代码
i = 11
while i < 15:
print("456")
i += 1
else:
print("123")
现在需要录入身边好友的信息,格式如下
------------ info of user ----------
Name :
Age :
job :
Hobbie:
------------- end ----------------
用print,过于死板,代码太长
name = input('请输入姓名:')
age = input('请输入年龄:')
job = input('请输入职业:')
hobby = input('请输入爱好:')
a = '------------ info of user ----------'
b = 'Name:'
c = 'Age:'
d = 'Job:'
e = 'Hobby:'
f = '------------- end ----------------'
print(a)
...
print(f)
# 运行结果
------------ info of user ----------
Name:123
Age:456
Job:456
Hobby:789
------------- end ----------------
使用字符串
name = input('请输入姓名:')
age = input('请输入年龄:')
job = input('请输入职业:')
hobby = input('请输入爱好:')
msg = '''
------------ info of Alex Li ----------
Name : %s
Age : %s
job : %s
Hobbie: %s
------------- end ----------------
'''
print(msg%(name,age,job,hobby))
%是一个占位,s是用来声明类型的,s是字符串类型
还有数字类型%d或%i,用来接收数字,
age = int(input("请输入你的年龄")) # 需要用int把输入的字符串变成整型
print("你的年龄是%d" % age)
%% 转义
number = input('>>>')
s= '目前学习进度:%s%%'%num #当出现%,解释器认为是占位,但是后面没有声明类型,出现错误,必须用%转义,这样解释器就认为这是一个%
print(s)
== != >= <= > <
= | 简单的赋值运算符 | a= b+c |
---|---|---|
+= | 加法赋值运算符 | a = a+c 等效于 a+=c |
-= | 减法赋值运算符 | a = a-c 等效于 a-=c |
/= | 除法赋值运算符 | a = a/c 等效于 a/=c |
*= | 乘法赋值运算符 | a = ac 等效于 a=c |
**= | 幂赋值运算符 | a = ac 等效于 a=c |
//= | 取整除赋值运算符 | a = a//c 等效于 a//=c |
%= | 取模赋值运算符 | a = a%c 等效于 a%=c |
运算符 | 描述 |
---|---|
and | 两边同为True,返回true |
or | 两边只要有一个true,返回true |
not | 取反 |
# True and False
# 数字非零的都是真
# and 的运算,都为真才是真,有一个是假就是假
# and 的运算,都为真的的时候选择and后边的内容
# and 的运算,都为假的的时候选择and前边的内容
# or 的运算,只要有一个真就是真
# or 的运算,都为真的的时候选择or前边的内容
# or 的运算,都为假的的时候选择or后边的内容
in,not in
判断元素是否在原字符串中,例如
print(‘x’ in ‘next’)
print(‘a’ in ‘love’)
只支持英文,不支持中文,占一个字节
兼容ASCLL码
占两个字节
为了兼容世界的所有语言,但是太过浪费资源
UTF-8为了节省资源,采用变长编码
英文1个字节
欧洲2个字节
亚洲3个字节
单位转化
8bit = 1byte
1024byte = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
1024TB = 1PB
1024TB = 1EB
1024EB = 1ZB
1024ZB = 1YB
1024YB = 1NB
1024NB = 1DB
常⽤到TB就够了
1.整型
2.布尔值
3.字符串
索引 切片 步长 字符串的方法
4.for循环
2进制 - 10进制
0 * 2 ** 0 + 1 * 2 ** 1 +1 * 2** 2+ 1 * 2 ** 3 +…
10进制 -2进制(断除法)
python中只要是引号引起来的就是字符串
字符串:用于数据存储,存储少量数据
字符串中每一个字符或者字母都成为元素
"name"
0123
-4-3-2-1
#从左往右排,一一对应,通过下标读取数据,从0开始
a = 'yi_yi_dui_ying'
print(a[5])
print(a[6])
...
#索引的时候不能超出最大索引值
# [索引值] [起始位置(包含):终止位置(不包含)]
a = 'yi_yi_dui_ying'
print(a[1:2])
print(a[-1:])
# print(a[:]) [(默认从最开始):(默认到最后)]
# 步长决定查找的方向 1是从左往右,-1是从右往左
练习
a = 'weixin,teng,腾讯,百度,阿里'
# 1.腾讯
print(a[12:14])
# 2.ii
print(a[2:6:2])
# 3.阿度
print(a[-2:-5:-2])
# 4.整体反转
print(a[::-1])
字符串是不可变数据类型,字符串是有序的
# name = "qwer"
# a = name.upper() # 全部大写
# print(a)
# print(name)
# name = "WQEW"
# a = name.lower() # 全部小写
# print(name)
# print(a)
# name = "qwer"
# print(name.startswith('e',2,3)) # 以什么开头 -- 返回的是布尔值
# print(name.endswith('l',0,2)) # 以什么结尾 -- 返回的是布尔值
# name = "alexwusirtaibIa"
# print(name.count("i")) # 统计,计数
user = input("user_name:").strip() # 去两边的空格制表符\n,换行符\t
# name = "xu_yu_wei"
# a = name.split("_") # 分割(默认空格,换行符\n,制表符\t)
# print(a) # ['xu','yu','wei']
# name = "alex,wusir,ta,i,b,a,i"
# a = name.replace(",",".") # 全部替换
# print(a)
# a = name.replace(",",".",4) # 可以指定替换的次数
# print(a)
# 字符串格式化(字符串的方法)
# name = "{}今年:{}".format("佳成",18) # 按照位置顺序进行填充
# print(name)
msg = "QWer"
# print(msg.isdigit()) # 判断字符串中的内容是不是全都是数字(阿拉伯数字)
# print(msg.isdecimal()) # 判断是不是十进制数
# print(msg.isalnum()) # 判断是不是数字,字母,中文
# print(msg.isalpha()) # 判断是不是字母,中文
# 总结:
# upper 全部大写
# lower 全部小写
# startswith 以什么开头
# endswith 以什么结尾
# count 计算出现的次数
# strip 去空格
# split 分隔符
# replace 替换符
# format 填充占位符
# isdecimal() 判断是不是十进制数
# isalnum() 判断是不是数字字母和中文
# isalpha() 判断是不是字母、中文
# isdigit() 判断字符串中的内容是不是全都是数字(阿拉伯数字)
# for 关键字
# i 变量名(可以任意修改)
# in 关键字
# msg 可迭代对象
# 可迭代对象: Python数据类型中 除了int,bool其余都可以迭代
msg = "文能提笔安天下,无能马上定乾坤"
for a in msg:
print(a)
print(a)
列表相比于字符串,不仅可以储存不同的数据类型,而且可以储存大量数据,是一种可变的数据类型
64位python的限制是 1152921504606846975 个元素。而且列表是有序的,有索引值,可切片,方便取值
lst = ['q','w','e','r',5,9]
lst.append(10) #追加,在最末尾的地方进行添加
lst.insert(2, 's') #插入,在指定的索引值进行添加
lst.extend([1,2,3,4]) #迭代添加,把迭代的元素一个一个添加进列表
for i in [1,2,3,4]:
lst.append(i) # 把数据一个一个添加进列表
lst = [1,3,4,5,6,34]
lst[1] = 99 #通过索引值删除
lst[1:3] = "20" #通过切片进行修改,默认步长是1,必须是可迭代对象,修改的内容可多可少
lst[1:5:2] = 1000,100 #步长不为1的时候,必须一一对应
lst = ['q','w','e','r']
print(repr(lst.pop(2))) #默认删除最后一个元素并返回,repr()查看当前数据的原生态
lst.clear() #清空列表
del lst[2]
del lst[0:2] # 通过切片删除
del lst[1:4:2] # 通过步长删除
lst = [1,1,8,7,9]
for循环
for i in lst:
print(i)
索引
lst[索引下标]
lst = ['one','two',['basketball',['dance','apple'],['score','qwer']],
['a','three','wqer']]
通过索引下标随便指定并取出
basketball
print(lst[2][1])
tuple不可变数据类型,只支持查询
tu = (1,2,3,4,5,6,7,8,9)
print(tu.count(1))
print(tu.index(2)) # 通过元素查询索引
range的诞生是为了解决不能循环数字
for i in range(2,10,2):
print(i)
for i in range(100):
print(i)
range(1,10) # [起始位置:终止位置] 顾头不顾尾
range(1,10,2) # [起始位置:终止位置:步长] 默认为 1
range(10) # 10代表的是终止位置,起始位置默认为 0
range是一个可迭代对象
语法:{
'key1':1,'key2':2}
注意:dict保存的数据不是按照我们添加进去的顺序保存的. 是按照hash表的顺序保存的. ⽽hash表 不是连续的. 所以不能进⾏切片⼯作. 它只能通过key来获取dict中的数据
列表可以存储大量的数据类型,但是只能按照顺序存储,数据与数据之间关联性不强。为了解决这一问题,就需要用字典。字典(dict)是python中唯⼀的⼀个映射类型.他是以{ }括起来的键值对组成
在dict中key是 唯⼀的.在保存的时候, 根据key来计算出⼀个内存地址. 然后将key-value保存在这个地址中.
这种算法被称为hash算法,key必须是可hash的
已知的可哈希(不可变)的数据类型: int, str, tuple, bool 不可哈希(可变)的数据类型: list, dict, set
注意: key必须是不可变(可哈希)的. value没有要求.可以保存任意类型的数据
注意:dict保存的数据不是按照我们添加进去的顺序保存的. 是按照hash表的顺序保存的. ⽽hash表 不是连续的. 所以不能进⾏切片⼯作. 它只能通过key来获取dict中的数据
dict = {
1:1,2:2,3:'3',4:'5'}
print(dict[1]) # 1
print(dict[4]) # '5'
注意:dict保存的数据不是按照我们添加进去的顺序保存的. 是按照hash表的顺序保存的. ⽽hash表 不是连续的. 所以不能进⾏切片⼯作. 它只能通过key来获取dict中的数据
dic = {
}
dic['name'] = '徐'
dic['age'] = 19
print(dic) # {'name': '徐', 'age': 19}
# 如果dict中没有出现这个key,就会将key-value组合添加到这个字典中
# 如果dict中没有出现过这个key-value. 可以通过setdefault设置默认值
dic.setdefault('雨隹',1)
print(dic) # {'雨隹': 1}
# 我们使用setdefault这个方法 里边放的这个内容是我们字典的健,后面写默认值,可不写,默认为None
dic.setdefault('雨隹',123)
# 这样就是不会进行添加操作了,因为dic这个字典中已经存在
# 总结: 当setdefault中第一个参数存在这个字典中就不进行添加操作,否则就添加
dic = {
'剑圣':'易','哈啥给':'剑豪','大宝剑':'盖伦'}
s = dic.pop('剑圣') # pop删除有返回值,返回的是被删的值
print(dic) # 打印删除后的字典
dic.popitem() # 随机删除 python3.6是删除最后一个
print(dic)
dic.clear() # 清空
dic = {
'剑圣':'易','哈啥给':'剑豪','大宝剑':'盖伦'}
dic['大宝剑'] = '德玛西亚'
print(dic)
dic.update({
'key':'v','哈啥给':'剑姬'})
# 当update中的字典里没有dic中键值对就添加到dic字典中,如果有就修改里边的对应的值,必须是字典
dic = {
'剑圣':'易','哈啥给':'剑豪','大宝剑':'盖伦'}
s = dic['大宝剑'] #通过健来查看,如果这个健不在这个字典中.就会报错
s1 = dic.get('剑圣') #通过健来查看,如果这个健不在这个字典中.就会返回None
s2 = dic.get('剑姬','可定义返回的结果') # 我们可以在get查找的时候自己定义返回的结果
keys() 获取所有的键
values() 获取所有的值
items() 获取所有的键值
for循环 -- 循环的是字典的键
for k,v in dic.items():
print('这是键',k)
print('这是值',v)
# 循环字典获取键和值
练习
dic = {
'k1': "v1", "k2": "v2", "k3": [11,22,33]}
请在字典中添加一个键值对,"k4": "v4",输出添加后的字典
请在修改字典中 "k1" 对应的值为 "alex",输出修改后的字典
请在k3对应的值中追加一个元素 44,输出修改后的字典
请在k3对应的值的第 1 个位置插入个元素 18,输出修改后的字典
a,b = 1,2
print(a,b) # 1 2
a,b = ('你好','世界')
print(a,b) # 你好,世界
a,b = {
'汪峰':'北京北京','王菲':'天后'}
print(a,b)
结果:
汪峰 王菲
解构可以将内容分别赋值到变量当中,我们使用解构就能够快速的将值使用
dic = {
101:{
1:{
"日魔":"对象"},
2:{
"隔壁老王":"王炸"},
3:{
"乔碧萝":("日魔","炮手","宝元")},
},
102:{
1:{
"汪峰":{
"国际章":["小苹果","大鸭梨"]}},
2:{
"邓紫棋":["泡沫","信仰","天堂","光年之外"]},
3:{
"腾格尔":["隐形的翅膀","卡路里","日不落"]}
},
103:{
1:{
"蔡徐坤":{
"唱":["鸡你太美"],
"跳":["钢管舞"],
"rap":["大碗面"],
"篮球":("NBA形象大使")}},
2:{
"JJ":{
"行走的CD":["江南","曹操","背对背拥抱","小酒窝","不潮不花钱"]}},
3:{
"Jay":{
"周董":["菊花台","双节棍","霍元甲"]}}},
201:{
1:{
"韦小宝":{
"双儿":"刺客","建宁":{
"公主":{
"吴三桂":"熊"}},"龙儿":{
"教主老婆":"教主"}}}
}
}
print(dic[201][1]["韦小宝"]["建宁"]["公主"]["吴三桂"])
# print(dic[103][1]["蔡徐坤"]["跳"][0][1])
# print(dic[102][2]["邓紫棋"][1])
练习
dic1 = {
'name':['alex',2,3,5],
'job':'teacher',
'oldboy':{
'alex':['python1','python2',100]}
}
1,将name对应的列表追加⼀个元素’wusir’。
2,将name对应的列表中的alex⾸字⺟⼤写。
3,oldboy对应的字典加⼀个键值对’⽼男孩’,’linux’。
4,将oldboy对应的字典中的alex对应的列表中的python2删除
== is id
== 判断两个值是否相等
is — 是 判断两个值的内存地址是否相等
代码块:一个py文件,一个函数,一个模块,终端中每一行都是代码块
代码块中有自己的内存空间:int ,str ,bool
int:-2~正无穷
a = -6
b = -6
print(a is b)
a = 1000
b = 1000
print(id(a), id(b))
print(a is b)
str:
bool:
True,False
小地址池 – int,str , bool
int:-5~ 256
str:
驻留机制:节省内存空间,提升效率(减少了开辟空间和销毁空间的耗时)
a = [1,2,3,4]
b = a
print(id(a),id(b))
print(a is b)
# a和b的内存地址一样,任何一个改,其他的改都改
# 在列表的元素中,元素是列表的情况下,拷贝的是内存地址
# 当内部的元素发生改变时,拷贝的列表和原列表都发生改变
a = [1,2,3,[4,5]]
b = a[:]
# 浅拷贝a[-1].append(6)
print(b)
import copy # 导入 copy模块
a = [1,2,3,[4,5],6]
b = copy.deepcopy(a)
print(id(a[-2]))
print(id(b[-2]))
print(a)
print(b)
print(a == b)
print(id(a),id(b))
print(a is b)
# 不可变数据类型内存地址共用,可变数据类型新开辟一个空间 不管嵌套多深
集合中的元素要求是不可变的并且还是唯一的,我们就利用它是唯一来做去重
集合 – set
s = {1,2,3,4}
集合就是一个没有值得字典,无序,可变; 值是唯一,不可变的
天然集合去重
s = {1,1,2,3,4,1,1,1,1}
s = {
} # 空字典
s1 = set() # 空集合
print(type(s1))
print(type(s))
s = set()
s.add('one')
s.update('two') #不建议使用
set('12345') #后面跟可迭代对象,只能迭代添加到空集合
s = {
100, 200 ,500 , 10 , 0.1, 0.5}
s.remove(500) # 通过元素删除
s.clear() # 清空列表
s.pop() # 随机删除
先删除,后添加,没有改的方法
for循环
s = {1, 24, 25, 48, 98, 56}
s_ = {1, 24, 25}
print(s - s1)
print(s1 - s)
print(s & s1)
print(s | s_)
print(s ^ s_)
print(s > s_)
print(s_ > s )
print(frozenset({1, 24, 5,4}))
str
a = "One two"
print(a.capitalize()) # 首字母大写
print(a.title()) # 每个单词首字母大写
print(a.swapcase()) # 大小写转换
print(a.center(20,"=")) # 居中 - 填充
print(a.find("c")) # 查找 通过元素查找索引,查找不到时返回-1
print(a.index("c")) # 查找 通过元素查找索引,查找不到时就报错
print("_".join(["1","2","4"])) # 拼接,将列表转换成字符串
str + str
str * 5
#字符串进行加操作,乘操作都是开辟新的空间
list
# 列表的一种定义方法
print(list('123445'))
# 列表的方法:
lst = [1,23,4,5,7,8,9]
print(lst.index(4)) # 通过元素查找索引
lst.sort() # 排序 默认是升序
lst.sort(reverse=True) # 降序
lst.reverse() #将源数据进行反转
print(lst)
lst = [1,5,7,9,4,23,546,78]
lst1 = lst[::-1] #不修改源数据进行反转
dict
dic = {
"key":1,"key1":2,"key2":4,"key3":1}
print(dic.popitem()) # 随机删除 python3.6版删除最后一个键值对
#popitem返回的是被删除的键值对
print(dic)
dic = {
}
dic = dic.fromkeys("abc",[])
print(dic)
dic["b"] = 11
dic["a"].append(10)
print(dic)
运行结果:
{
'a': [], 'b': [], 'c': []}
{
'a': [10], 'b': 11, 'c': [10]}
fromkeys 第一个参数必须是可迭代对象,会将可迭代对象进行迭代,成为字典的键.第二个参数是值(这个值是共用的)
fromkeys 共用的值是可变数据类型就会有坑,不可变数据类型就没事
基础数据类型总结:
可变,不可变,有序,无序
1.可变:
list
dict
set
2.不可变:
int
str
bool
tuple
3.有序:
list
tuple
str
4.无序:
dict
set
取值方式:
1.索引
list
tuple
str
2.键
dict
3.直接
int
bool
set
数据类型转换
str -- int
int -- str
str -- bool
bool -- str
int -- bool
bool -- int
重要: *****
list -- str
lst = ["1","2","3"]
print("".join(lst))
str -- list
s = "alex wusir 太白"
print(s.split())
目前字典转换,自己实现方法
重点:
find
join
列表乘法
元组(1,)
list -- str
str -- list
lst = [1,2,3]
for i in lst:
lst.append(4)
# 错误示范
lst = [11,22,33,44]
for i in lst:
lst.remove(i)
print(lst)
# 正确代码
lst = [11,22,33,44]
for i in range(len(lst)):
del lst[-1]
print(lst)
for i in range(len(lst)):
lst.pop()
print(lst)
# 创建一个浅拷贝的列表,循环它的次数,删除源数据的数据
lst = [11,22,33,44]
lst1 = lst[:]
for i in lst1:
lst.remove(i)
print(lst)
使用for循环清空列表元素内容 1.从后向前删除, 2.创建一个新的容器,循环新的容器删除旧的容器内容
面试题:
lst = [1,[2]]
lst[1] = lst
print(lst)
答案: [1, [...]]
dic = {
"key":1,"key1":2}
for i in dic:
if i == "key1":
dic[i] = dic[i] + 8 # dic[i] = 10
else:
print("没有这个键!")
print(dic)
字典和集合在遍历(循环)时不能修改原来的大小(字典的长度),可以进行修改值
# 以下会报错
s = {
1,2,3,4,5,6}
for i in s:
s.pop()
print(s)
Set changed size during iteration
# python3: 默认编码unicode
# pyhton2:默认编码ascii,不支持中文
print(s.encode(“UTF-8”)) # 中⽂编码成UTF-8 print(s.encode(“GBK”)) # 中⽂编码成GBK 结果: b’\xe4\xb8\xad’ b’\xd6\xd0’
解码 print(s.decode(“utf-8”)) print(s.decode(‘gbk’))
文件操作
r模式
f = open('test.txt', mode='r', encoding='utf-8')
print(f.read())
f.close()
with open('test.txt', 'r', encoding='utf-8')as f:
print(f.read())
# 两种方式获得文件句柄,推荐with,运行完之后自动关闭文件
rb模式
with open('test.txt', 'rb', encoding='utf-8')as f:
print(f.read())
# 读出来的是字节
建议使用相对路径
读操作
f.read() # 不建议用
f.read(读取的字符数)
f.readline() # 每次读取一行,每行最后有一个\n
f.readlines() # 将每一行形成一个元素,并添加到一个列表中,当文件过大时,内存会崩
推荐使用,先拿到文件句柄
with open('1','r',encoding='utf-8')as f:
for i in f:
print(i)
使用w模式的时候,在打开文件的时候就就会把文件中的所有内容都清空,然后在操作
如果文件不存在使用w模式会创建文件,文件存在w模式是覆盖写,在打开文件时会把文件中所有的内容清空.
f.write()
wb模式下,不可以指定打开文件的编辑,但是写文件的时候必须将字符串转换成utf-8的bytes数据
只要是a或者ab,a+都是在文件的末尾写入,不论光标在任何位置.
在追加模式下,我们写入的内容后追加在文件的末尾
a模式如果文件不存在就会创建一个新文件
ab模式和上面一样,没有太大区别
# 面试题:
# 当文件较大时,使用for循环进行读取
# f = open('t1',mode="r",encoding="utf-8")
# for i in f:
# print(i.strip())
r+模式一定要记住是先读后写
f1 = open('test.txt',mode='r+',encoding='utf-8')
msg = f1.read()
f1.write('千山鸟飞绝,万径人踪灭')
f1.flush()
f1.close()
print(msg)
结果:
正常的读取之后,写在结尾
深坑请注意: 在r+模式下. 如果读取了内容. 不论读取内容多少. 光标显示的是多少. 再写入 或者操作文件的时候都是在结尾进行的操作.
先将所有的内容清空,然后写入.最后读取.但是读取的内容是空的,不常用
a+模式下,不论是先读还是后读,都是读不到数据的
seek()
seek(n)光标移动到n位置,注意: 移动单位是byte,所有如果是utf-8的中文部分要是3的倍数
通常我们使用seek都是移动到开头或者结尾
移动到开头:seek(0,0) 可以看做成seek(0)
seek(6)这种如果是单数并且不是0的就是按照字节来移动光标
移动到结尾:seek(0,2) seek的第二个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾
tell()
使用tell()可以帮我们获取当前光标在什么位置
文件修改: 只能将文件中的内容读取到内存中, 将信息修改完毕, 然后将源文件删除, 将新文件的名字改成老文件的名字
错误示范,使用read,当文件内容过大,会导致内存溢出
import os
with open("../path1/小娃娃", mode="r", encoding="utf-8") as f1,\
open("../path1/小娃娃_new", mode="w", encoding="UTF-8") as f2:
content = f1.read()
new_content = content.replace("冰糖葫芦", "⼤白梨")
f2.write(new_content)
os.remove("../path1/小娃娃") # 删除源文件
os.rename("../path1/小娃娃_new", "小娃娃") # 重命名新文件
弊端: ⼀次将所有内容进行读取. 内存溢出. 解决方案: 一行一行的读取和操作
正确代码:
import os
with open("小娃娃", mode="r", encoding="utf-8") as f1,\
open("小娃娃_new", mode="w", encoding="UTF-8") as f2:
for line in f1:
new_line = line.replace("大白梨", "冰糖葫芦")
f2.write(new_line)
os.remove("小娃娃") # 删除源⽂文件
os.rename("小娃娃_new", "小娃娃") # 重命名新文件
# 通过定义一个计算数据长度的函数,def为关键字,count_len是函数名
def count_len():
lst = [1, 2, 5]
count = 0
for i in lst:
count += 1
# 通过函数名调用
count_len()
def return_len():
return 'len'
a = return_len()
print(a)
return:
# 1.return可以返回任意类型数据
# 2.返回多个内容是元组的形式
# 3.下方不执行,并且会终止当前这个函数
# 4.不写或者return后不写,都返回None
def yue(app1,app2,app3,app4):
print(app1)
print(app2)
print(app3)
print(app4)
yue('qq','weixin','taobao','zhifubao')
函数的参数:
形参:定义的时候定义的参数
位置参数: 一一对应 关键字参数: 按照名字进行传参 混合参数: 位置参数和关键字参数一起使用
实参:实际传入的参数
位置参数: 一一对应 关键字参数: 按照名字进行传参 混合参数: 位置参数和关键字参数一起使用
传参:从调用函数的时候将值传递到定义函数的过程叫做传参
注意点: 参数名字不能重复,优先级不能放反
位置参数 > 默认参数
位置参数是一一对应
参数传递后,可以不使用
return 不能终止循环
c = a if a > b else b
条件成立的结果(a) 条件(if a > b else) 条件不成立的结果(b)
条件成立的结果 条件 条件不成立的结果
# 动态位置参数
# def eat(*args): # 函数的定义阶段 *聚合(打包)
# print(args) # tuple
# print(*args) # 函数体中的*表示打散(解包)
def eat(*args):
pirnt('我想吃',args)
eat('大米饭', '米饭', '饭')
# 收到的结果是一个tuple元组
动态接收参数的时候:动态参数必须在位置参数后面
无论是否给*args值,它都是一个元组(),若不给值,就是()
def eat(a, b,*args):
print("我想吃",args,a,b)
eat('大米饭','米饭','饭')
# 我想吃 ('饭',) 大米饭 米饭
# 默认参数放在最后边,通过关键字传参
def eat(a,b,*args,c='白菜'):
print('我想吃',a,b,args,c)
eat('猪肉','粉条','豆腐','大葱')
结果:
我想吃 猪肉 粉条 ('豆腐', '大葱') 白菜
注意: 形参的顺序: 位置参数 , 动态参数 , 默认参数
def func(*args,**kwargs):
print(args,kwargs)
lst = [1,23,5]
dic = {
'k1':4, 'k2':5}
func(*lst,**kwargs)
func(1,23,5,k1=4,k2=5)
最终顺序:
位置参数 > *args(动态位置参数) > 默认值参数 > **kwargs(动态默认参数)
# 总结:
# *args(聚合位置参数) 大家伙都用的名字, 可以进行修改但是不建议修改
# **kwargs(聚合关键字参数) 大家伙都用的名字, 可以进行修改但是不建议修改
# 函数的定义阶段 * 和 ** 都是聚合
# 函数体中 * 就是打散, *args将元组中的元组进行打散 *kwargs将字典的键获取
# 实参和函数体:
# * 打散
# ** 实参时能够使用
def func(a, b):
"""
计算两数相加
:param a:
:param b:
:return: a + b
"""
return a + b
func(1, 10)
# print(a.__doc__)
# print(b.__doc__) # 查看函数的注释
# print(a.__name__) # 查看函数的名字
内置空间:Python解释器自带的空间
全局空间:py文件中顶格写的就是全局空间
局部空间:函数中就是局部空间
# 1.局部空间
# 2.全局空间
# 3.内置空间
# 1.内置空间
# 2.全局空间
# 3.局部空间
不管在什么位置,只要是函数名()就是在调用一个函数
global : 只修改全局,如果全局没有就创建一个全局变量
nonlocal : 只修改局部,修改离nonlocal最近的一层,上一层没有继续向上上层查找.只限在局部
a = 10
def func():
global a # 声明之后,就可以对全局变量进行修改
a += 1
print(a)
func()
# nonlocal只能修改离nonlocal最近的一层,且不包括全局变量,如果没有就报错
def run():
a = 19
def func():
print('123')
def fun():
nonlocal a
a = 10
print(a)
fun()
run()
函数名的第一类对象及使用
f-strings
迭代器
f-strings
# f"{变量名}"
# F"{变量名}"
# f"""{变量名}"""
# f"{input()}"
# f"{3 if 3>2 else 2}"
# lst = [1,2,3,4,5]
# f"{lst[4]}"
# f"{lst[-1]}"
# f"{dic['key1']}"
可迭代对象:
只要具有__iter__()方法就是一个可迭代对象
迭代器:
具有__iter__()和__next__()两个方法才是迭代器
lst = [1, 2, 3, 4]
# l = iter(lst) #变成迭代器,建议使用iter()
l = lst.__iter__() # 将可迭代对象转换成迭代器
print(l.__nexr__()) # 获取一个值
print(l.__nexr__()) # 每一行获取一个值,当超过索引的时候会报错,并且只能从头到尾,不可逆
迭代器的优点
迭代器的缺点
1.不能直接查看值,迭代器查看到的是一个迭代器的内存地址
2.一次性,用完就没有了
3.不能逆行
时间换空间: 迭代器就是节省了空间,但是取值时间较长
空间换时间: 容器存储大量的元素,取值时 取值时间短,但是容器占用空间较大
迭代器是基于上一次停留的位置,进行取值
可迭代对象:具有iter()方法就是一个可迭代对象
迭代器:具有iter()和next()方法就是一个迭代器
# while True:
# try:
# print(l.__next__())
# except StopIteration:
# break
# 里面有一个捕捉异常的机制,所以取值不会超
# pyhton3:
# iter()和 __iter__() 都有
# next()和__next__()都有
# python2:
# iter()
# next()
生成器
推导式
内置函数一
什么是生成器?生成器的本质就是一个迭代器
生成器编写方式:
def func():
print('这是一个函数')
return '函数'
func()
def func():
print("这是一个生成器")
yield '生成器'
# 坑!!!,其实这个生成器只能执行一个next,因为只有一个yield
func() # 生成一个生成器
print(func().__next__()) # 启动生成器
print(func().__next__())
# 上方这句代码的意思是:创建一个生成器并且执行一个next方法,两句一样但互不相干
函数体中出现yield代表要声明一个生成器
def func():
msg = input("请输入内容")
yield msg
print("这是第二次启动")
yield "生成器2"
yield "生成器3"
yield "生成器4"
g = func()
print(next(g))
print(next(g))
print(next(g))
print(next(g)) # 不能超过yield次数
相同点:
不同点:
一个yield对应一个next
# 生成器的作用是节省空间
# 可迭代对象:
# 优点: list,tuple,str 节省时间,取值方便,使用灵活(具有自己私有方法)
# 缺点: 大量消耗内存
# 迭代器:
# 优点:节省空间
# 缺点:不能直接查看值,使用不灵活,消耗时间,一次性,不可逆行
# 生成器:
# 优点:节省空间,人为定义
# 缺点:不能直接查看值,消耗时间,一次性,不可逆行
# 使用场景:
# 1.当文件或容器中数据量较大时,建议使用生成器
# 数据类型 (pyhton3: range() | python2 :xrange()) 都是可迭代对象 __iter__()
# 文件句柄是迭代器 __iter__() __next__()
没有send方法就是一个迭代器,具有send方法的就是一个生成器
def func():
lst = [1,2,3,45,6]
lst1 = ["alex","wusir","taibi","baoyuan"]
yield from lst
yield from lst1
# yield 将可迭代对象一次性返回
# yield from 将可迭代对象逐个返回
g = func()
for i in g:
print(i)
列表推导式:
普通循环
print([i for i in range(10)])
print([变量 for循环])
筛选
lst = []
print([i for i in range(10) if i % 2 == 0])
print([i for i in range(10) if i > 2])
[操作后的变量 for循环 判断操作]
集合推导式:
普通循环
print({
i for i in range(10)})
{
变量 for循环}
筛选
print({
i for i in range(10) if i % 2 == 1})
{
操作后的变量 for循环 操作}
字典推导式:
普通循环
print({
i: i+1 for i in range(10)})
{
键:值 for循环}
筛选模式
print({
i:i+1 for i in range(10) if i % 2 == 0})
{
操作的键:值 for循环 操作}
生成器推导式:
普通模式
tu = (i for i in range(10))
(变量 for循环)
筛选模式
tu = (i for i in range(10) if i > 5)
(操作后的变量 for循环 操作)
all() 判断容器中的元素是否都为真
any() 判断容器中的元素是否有一个为真
bytes() 将字符串进行编码
callable() 查看对象是否可 调用 == ()
chr() 通过表位序号查找元素
complex() 复数
eval() 神器一
exec() 神器二 神器禁止使用
frozenset() 冻结集合
globals() 查看全局空间变量
hash() 区分可变数据类型和不可变数据类型
help() 查看帮助信息
id() 查看内存地址
locals() 查看当前空间变量
oct() 十进制转八进制
ord() 通过元素获取当前unicode表位的序号
pow() 幂,两个参数是求幂,三个参数时求幂后在取余
repr() 查看数据的原生态
round() 保留小数位
divmod() 求商和余
bin() 十进制转二进制
匿名函数就是一行函数,关键字是lambda
lambda x:x
# lambda 参数:返回值
x 是普通函数的形参 可以不定义形参
:x 是 普通函数的返回值(只能返回一个数据类型)
f = lambda x:x+6
print(f(1)) # 结果:7
print(f.__name__) # 查看函数的名字 函数名为lambda
lst = [lambda :i for i in rang(5)]
print(lst[0]())
# 结果:4
面试题拆解:
lst = []
for i in range(5):
def func():
return i
lst.append(func)
字典的合成方式
dict([(1,2),(3,4)]) # 中括号也可以换成小括号
# {1: 2, 3: 4}
dict(k=1,v=2,c=3)
# {'k': 1, 'v': 2, 'c': 3}
dic1 = {
"key1":1,"key2":2}
dic2 = {
"a":1,"b":2}
print(dict(**dic1,**dic2))
# {'key1': 1, 'key2': 2, 'a': 1, 'b': 2}
sep:每个元素之间分割的字符,默认是" "空格
end:print执行完后的结束语句,默认是\n
file:文件句柄,默认是显示到屏幕,也可以写进文件,例如:
print(1,2,3,4,file=open("test","w",encoding="utf-8"))
算出可迭代对象中的和,只能算int
绝对值
print(dir(list))
print(dir(str))
# 查看当前对象所有方法,返回的是列表
拉链
lst1 = [1,2,3,4]
lst2 = ['a','b','c','d','e']
面试题:
print(dict(zip(lst1,lst2)))
# {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
print(format('alex','>20')) # 左对齐
print(format('alex','<20')) # 右对齐
print(format('alex','^20')) # 居中
进制转换
print(format(10, "b")) # bin 二进制
print(format(10, "08o")) # oct 八进制
print(format(10, "08x")) # hex 十六进制
print(format(0b1010), "d") # 十进制
反转
print(list(reversed("alex")))
# 得到的是迭代成列表之后的反转
# 得到的是一个新列表
过滤
lst = [1,2,3,4,5,6]
print(list(filter(lambda x:x>1,lst)))
# 过滤掉大于1的数字
lst = [{
'id':1,'name':'alex','age':18},
{
'id':1,'name':'wusir','age':17},
{
'id':1,'name':'taibai','age':16},]
print(list(filter(lambda x:x['age']>16,lst)))
# 留下年龄大于16的信息
映射函数(将可迭代对象中的每个元素执行指定的函数)
print(list(map(lambda x,y:x+y,[1,2,3],[11,22,33,44])))
# 将每个列表的对应元素相加
print([i*8 for i in [1,2,3,4]])
# 8,16,24,32
print(sorted([1,-22,3,4,5,6],key=abs)) # key指定排序规则
# 排序 执行了绝对值之后的列表
lst = ["三国演义","红楼梦","铁道游击队","西游记","水浒传","活着"]
print(sorted(lst,key=len))
# 通过长度排序
lst = [{
"age": 19}, {
"age1": 20}, {
"age2": 80}, {
"age3": 10}]
# print(sorted(lst, key=lambda x: x.values()))
print(sorted(lst, key=lambda x: x.keys(), reverse=True))
# 通过键和值排序
最大值和最小值
from functools import reduce # 累计算
# 内部实现原理
def func(x,y):
return x+y
print(reduce(func,[1,2,3,4,5]))
print(reduce(lambda x,y:x+y,[1,2,3,4,5]))
闭包
# 1.在嵌套函数中,使用非本层且非全局变量的就是闭包
# print(inner.__closure__) 判断是否是闭包 返回None就不是
# 闭包的作用:
# 1.保护数据的安全性
# 2.装饰器
装饰器
# 开放封闭原则
- 1.对扩展是开放的
- 2.对修改是封闭的
# 在不修改源代码和调用方式的情况下,对函数进行扩展
# 第一版装饰器
def times(func):
def foo():
print('装饰001')
func()
print('装饰002')
return foo
def func1():
print("今天是个好日子1")
func1 = times(func1)
func1()
# python内置的语法糖
# 要将语法糖放在被装饰的函数正上方
def times(func):
def foo():
print('装饰001')
func()
print('装饰002')
return foo
@times
def func1(): # func1 = times(func1)
print("被装饰的函数1")
@times
def func2(): # func2 = times(func2)
print("被装饰的函数2")
func1()
# 有参数的函数语法糖
def func(func):
def foo(*args, **kwargs):
print('装饰001')
func(*args, **kwargs)
print('装饰002')
return foo
@func
def func1(*args, **kwargs):
print(args,kwargs)
print('被装饰的函数1')
@func
def func2(*args, **kwargs):
print(args,kwargs)
print('被装饰的函数2')
func2(5)
# 要求
#博客园登陆之后有几个页面,diary,comment,home,如果我要访问这几个页面,必须验证我是否已登录。 如果已经#成功登录,那么这几个页面我都可以无阻力访问。如果没有登录,任何一个页面都不可以访问,我必须先登录,登录成功#之后,才可以访问这个页面。
user_status = {
'user_name': None,
'user_status': False
}
def auth(func):
def foo():
if user_status['user_status']:
ret = func()
return ret
user_name = input('name:')
user_pwd = input('pwd:')
if user_name == 'xuhuo' and user_pwd == '123456':
user_status['user_status'] = True
ret = func()
return ret
return foo
@auth
def zhu_ye():
print('欢迎来到博客园主页。')
@auth
def dirary():
print('欢迎来到博客园的日记页面。')
@auth
def ping_lun():
print('欢迎来到评论页面。')
@auth
def sui_bi():
print('欢迎来到随笔页面。')
zhu_ye()
sui_bi()
dirary()
ping_lun()
带参数装饰器
多个装饰器修饰一个函数
递归
# 判断argv,当登录不同的网页,会有不同的装饰效果
def auth(argv):
def warpper(func):
def inner():
if argv == '博客园':
func()
elif argv == '码云':
func()
return inner
return warpper
@auth('博客园')
def home_page0():
print('欢迎来到博客园主页')
@auth('码云')
def home_page1():
print('欢迎来到码云主页')
home_page0()
home_page1(
# 多个函数装饰一个函数时,先执行离被装饰函数最近的装饰器
def auth(func): # wrapper1装饰器里的 inner
def inner(*args,**kwargs):
print("额外增加了一道 锅包肉")
func(*args,**kwargs)
print("锅包肉 38元")
return inner
def wrapper1(func): # warpper2装饰器里的 inner
def inner(*args,**kwargs):
print("额外增加了一道 日魔刺生")
func(*args,**kwargs)
print("日魔刺生 白吃")
return inner
def wrapper2(func): # 被装饰的函数foo
def inner(*args,**kwargs):
print("额外增加了一道 麻辣三哥")
func(*args,**kwargs)
print("难以下嘴")
return inner
@auth # 1 7
@wrapper1 # 2 6
@wrapper2 # 3 5
def foo(): # 4
print("这是一个元宝虾饭店")
foo()
递归
1.不断调用自己本身
2.有明确的终止条件
递归的最大深度,官方说明是1000,实际测试是994/997/998
# 循环一个列表,打印出每一个元素
li = [1, 3, 4, "alex", [3, 7, 8, "TaiBai"], 5, "RiTiAn",[4,5,6,[7,[11,12,34,5],10,8,9]]]
def func(lst):
for i in lst:
if type(i) == list:
func(i)
else:
print(i)
func(li)
# import 模块 例:import time
# 导入的是time模块中所有的内容(变量,函数名,类名等)
# import做的三件事:
1.将文件中的所有代码读取到当前文件
2.当前文件开辟空间
3.等待被调用
# 被导入模块有独立的名称空间,定义模块中得全局变量不会产生冲突
示例:
# module_one.py
name = 'xuhuo'
def func():
print("这是第一个模块中的函数")
# module_two.py
import module_one
name = 'xuyuwei'
def func():
print('这是第二个模块的函数')
func()
module_one.func()
模块二的执行的结果:
这是第二个模块的函数
这是第一个模块中的函数
# 为模块起别名
import time as f
通过 f.name 调用 f.变量或者函数
# 导入多个模块时写法
import os
import sys
import json
# from...import..
# 自己写模块module_one 和 module_two
# module_one中导入module_two模块中的func函数
from module_two import func()
from和import的对比,from直接把导入的函数或变量直接放在当前的名称空间中。所以在当前名称空间中,直接使用名字就可以了,无需加前缀
好处:使用更方便
坏处:容易和当前执行文件中的名字冲突
# 当执行文件与模块同名的变量或者函数名,会有覆盖效果
from datetime imoirt datetime as date
d = date.now() # 获取当前时间
# 一行可导入多个
__all__=['name','read1']
#这样在另外一个文件中用from spam import *就这能导入列表中规定的两个名字
1.脚本,一个文件就是整个程序(例如博客园登录作业等)
2.模块,文件中存放着一堆功能,用来导入使用
if __name__ == '__main__':
func()
print(name)
# 当被导入其他文件时不执行,只有自己运行时,才运行的调试代码,不被导入
# 用来控制.py文件在不同的应用场景下执行不用的逻辑(或者是在模块文件中测试代码)
# 内存中已经加载的模块->内置模块->sys.path路径中包含的模块
#1.在第一次导入某个模块时(比如meet),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用(ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看)
#2.如果没有,解释器则会查找同名的内置模块
#3.如果还没有找到就从sys.path给出的目录列表中依次寻找meet.py文件。
import time
# 这是一个时间模块,通常用于获取当前时间或时间戳等等
1.时间戳:时间戳表示的是格林尼治时间是从1970年1月1日00:00:00开始按秒计算的偏移量,每一刻都在变化(返回的是float类型)
2.格式化时间,格式化的时间字符串(1999-12-06)
python中时间日期格式化符号:
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
结构化时间元组(struct_time)元组共有9个元素(年,月,日,时,分,秒,一年中的第几周,一年中第几等)
import time
# 获取当前时间戳
print(time.time())
# 将时间戳转换成结构化时间,元组形式
print(time.localtime(time.time()))
# 将结构化时间转换成字符串
time_t = time.localtime()
print(time.strftime('%Y-%m-%d %H:%M:%S', time_t))
# 休眠,单位秒
time.sleep(3)
# 将字符串转换成结构化时间
str_time = "2019-8-22 10:11:22"
time_g = time.strptime(str_time, "%Y-%m-%d %H:%M:%S")
print(time_g)
# 将结构化时间转换成时间戳
print(time.mktime(time.localtime()))
# 总结:
# time.time() 时间戳
# time.sleep() 睡眠
# time.localtime() 时间戳转结构化
# time.strftime() 结构化转字符串
# time.strptime() 字符串转结构化
# time.mktime() 结构化转时间戳
# %Y 年
# %m 月
# %d 日
# %H 时间
# %M 分钟
# %S 秒
from datetime import datetime,timedelta
# print(datetime.now()) # 获取当前时间
# 算两个时间差几天几个小时几分钟,自己指定时间
# print(datetime(2018,10,1,10,11,12) - datetime(2011,11,1,20,10,10))
# 将对象转换成时间戳
# d = datetime.now()
# print(d.timestamp())
# 将时间戳转换成显示的时间对象
# f_t = time.time()
# print(datetime.fromtimestamp(f_t))
#将对象转换成字符串
# d = datetime.now()
# print(d.strftime("%Y-%m-%d %H:%M:%S"))
# 将字符串转换成对象
# s = "2018-12-31 10:11:12"
# print(datetime.strptime(s,"%Y-%m-%d %H:%M:%S"))
# 可以进行加减运算
# from datetime import datetime,timedelta
# 减去一天
# print(datetime.now() - timedelta(days=1))
# 减去一个小时
# print(datetime.now() - timedelta(hours=1))
import random
# 随机产生一个1-50之间的整数,包括1
print(random.randint(1,50))
# 随机产生一个0-1之间的随机小数,不包括1
print(random.randon())
# 1-10之间随机小数,不包括10
print(random.uniform(1, 10))
# 从容器中随机选择一个,参数是可迭代类型
print(random.choice((1,2,6,7,9,8)))
# 从容器中随机生成n个元素,以列表的形式返回,会出现重复元素
print(random.choices((1,7,8,6,5,48,94,43,16),k = n))
# 从容器中随机选择n个元素,以列表的形式返回,不会出现重复元素
print(random.sample((1,7,8,9,4,3,78,89,45,56),k=n)
# 随机奇数或随机的偶数
print(random.randrange(1,10,2))
lst = [1,8,9,7,45,76]
random.shuffle(lst)
# 洗牌,将有序的数据打散
print(lst)
目录结构
bolg项目名字
bin启动文件
starts.py
conf配置文件
setting.py
log日志文件
logg.log
db数据文件
register
lib公共组件
common.py
core主逻辑文件
src.py
src1.py
import os # os是和操作系统做交互,给操作发指令
print(os.getcwd()) # 获取当前文件工作的路径
os.chdir("F:\Python全栈\S25") # 路径切换
print(os.getcwd()) # 获取当前文件工作的路径
print(os.curdir) # 返回当前目录:('.')
print(os.pardir) # 获取当前目录的父目录字符串名('..')
# 文件夹
# os.mkdir('a2') # 创建文件夹
# os.rmdir('a2') # 删除文件夹
# os.makedirs('a1/a2/a3') # 递归创建文件夹
# os.removedirs('a1/a2') #递归删除文件夹
print(os.listdir(r'F:\Python全栈\S25\day17模块')) #查看当前文件下的所有内容
# 文件
# os.remove(r'F:\Python全栈\S25\day17模块\a2') # 删除文件
# os.rename('a2','a1') # 重命名
# 路径
# 返回文件的绝对路径:
# print(os.path.abspath('a1'))
# 将路径分割成一个路径和一个文件名,返回元组,路径和文件名:
# print(os.path.split(r'F:\Python全栈\S25\day17模块'))
# 获取父目录:
# print(os.path.dirname('F:\Python全栈\S25\day17模块'))
# 获取文件名:
# print(os.path.basename('F:\Python全栈\S25\day17模块'))
# 路径拼接:
print(os.path.join('F:\Python全栈','S25\day17模块','模块测试'))
# 判断
# print(os.listdir()) # 展示当前文件的所有文件
# 判断当前路径是否存在:
# print(os.path.exists(r'F:\Python全栈\S25\day17模块\blog'))
# 判断是不是绝对路径:
# print(os.path.isabs(r'F:\Python全栈\S25\day17模块\blog'))
# 判断是不是文件夹:
# print(os.path.isdir(r'F:\Python全栈\S25\day17模块\blog'))
# 判断是不是文件:
# print(os.path.isfile(r'F:\Python全栈\S25\day17模块\blog'))
# 获取文件或文件大小:
print(os.path.getsize(r'F:\Python全栈\S25\day17模块\a1'))
print(os.path.getsize(r'F:\Python全栈\S25\day17模块\blog'))
import sys # sys和python解释器做交互
print(sys.path) # 模块查找的顺序
print(sys.argv) # 只能在终端执行
print(sys.modules) #查看加载到内存的模块
print(sys.platform) #查看当前操作系统平台
print(sys.version) # 查看当前解释器的版本
import json
import pickle
#json模块 :(重点)
1.不同语言都遵循的一种数据转化格式,即不同语言都使用的特殊字符串。(比如Python的一个列表[1, 2, 3]利用json转化成特殊的字符串,然后在编码成bytes发送给php的开发者,php的开发者就可以解码成特殊的字符串,然后在反解成原数组(列表): [1, 2, 3])
2.json序列化只支持部分Python数据结构:dict,list, tuple,str,int,float,True,False,None
tuple序列化之后是列表的形式
# pickle模块:
只能是Python语言遵循的一种数据转化格式,只能在python语言中使用。
支持Python所有的数据类型包括实例化对象。
import json
dic = {
'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = json.dumps(dic) # 将字典转化成字符串
print(str_dic, type(str_dic))
# 将字符串的字典转化成字典
d = json.loads(str_dic) # 用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(d, type(d))
# 列表之间的转化
lst = [1, 8, 7, 9, 4, 3, 84, 95, 35, 75, 86, 94, 81]
lst1 = json.dumps(lst)
print(lst1, type(lst1))
lst2 = json.loads(lst1)
print(lst2, type(lst2))
# 将字典写入到文件中,然后读取出来
dic = {
'key': 'v1'}
json.dump(dic, open('a1', 'a', encoding='utf-8'))
print(json.load(open('a1', 'r', encoding='utf-8')))
# json序列化存储多个数据到一个文件中是有问题的,默认一个json文件只能才能存储一个json数据,但是可以解决
dic = {
"key": "v1"}
f = open("a", "a", encoding="utf-8")
f.write(json.dumps(dic) + "\n")
f.write(json.dumps(dic) + "\n")
f.write(json.dumps(dic) + "\n")
f.write(json.dumps(dic) + "\n")
f.close()
f1 = open("a", "r", encoding="utf-8")
for i in f1:
print(json.loads(i), type(json.loads(i)))
f.close()
pickle
# pickle模块是将Python所有的数据结构以及对象等转化成bytes类型,然后还可以反序列化还原回去。
# 只有python中有,几乎可以序列python中所有数据类型,匿名函数不能序列
import pickle
def func():
print(1)
a = pickle.dumps(func) # 将源数据类型转换成类似字节的内容
print(pickle.loads(a)) # 将类似字节的内容转换成源数据类型
什么是编程语言?什么语言?为什么要有编程语言?
编程语言的本质就是一门语言
语言就是一种事物与另外一种事物沟通的表达方式/工具
人--------------人类的语言------------>奴隶
人--------------编程语言------------->计算机
什么编程?为什么要编程?
编程就是人把自己想计算机做的事,也就是自己的思维逻辑,用编程语言表达出来
编程的目的就是让计算机按照人类的思维逻辑去工作,从而解放人力
1.什么是计算机
计算机俗称“电脑”,包含人对计算机的终极期望,能够真的像人脑一样去工作
2、为何要有计算机
为了执行人类的程序,从而把人类解放出来
大前提:计算机所有的组成都是模仿人的某一功能或器官
3、计算机的组成
控制器:
作用:是计算机的指挥系统,负责控制计算机所有其他组件如何工作的
类比:控制器=》人类的大脑
运算器:
作用:运算包括数学运算与逻辑运算
类比:运算=》人类的大脑
控制器+运算器=》cpu===》人类的大脑
存储器/IO设备
作用:是计算机的记忆功能,负责数据的存取
分类:
内存(基于电工作):存取数据都快,断电数据丢失,只能临时存取数据
外存(硬盘,基于磁工作):存取速度都慢,断电数据也不丢,可以永久保存数据
类比:
内存===》人类的大脑的记忆功能
外存===》人的笔记本
输入设备input
如键盘、鼠标
输出设备output
如显示器、打印机
4、一个程序的运行与三大核心硬件的关系
人--------------编程语言------------->计算机
程序如下:
1、去包子店
2、付钱
3、把包子送回来
总结:
程序最先是存放于硬盘之上
程序的运行一定事先把程序的代码加载到内存
然后cpu从内存中读取指令执行
三:操作系统
1、引入
用户/应用程序(暴风影音、腾讯qq、快播、哇嘎)
操作系统:控制程序(windows、linux)
计算机硬件
2、操作系统概念
操作系统是一个协调、管理、控制计算机硬件资源与应用软件资源的一个控制程序
作用:
1、控制计算机硬件的基本运行
2、把使用硬件的复杂操作封装成简单的功能,给上层的应用程序使用
例如:文件就是操作系统提供给应用程序/用户操作硬盘的一种功能
3、程序的区分
计算机硬件是死的,计算机硬件的运行都受软件控制,所以说,软件相当于计算机的灵魂
具体来说软件分为两种:
1、应用软件:应用程序相关逻辑
2、系统软件:控制底层硬件的
4、计算机系统三层结构
应用程序
操作系统
计算机硬件
5、平台
计算机硬件+操作系统=》平台
软件的跨平台性指的是:一款软件可以任意平台上运行,是衡量软件质量高低的一个非常重要的指标
人---------编程语言--------》计算机
去包子店
付款
把包子送回来
1、计算机硬件
(运算器,控制器)=》CPU
负责运行人类程序的硬件是cpu
存储器
内存:存取速度都快,基于电工作的,断电数据就丢失,不能永久保存数据=========》人脑的记忆功能
外存(磁盘):存取速度都慢,基于磁工作的,断电数据不丢失,可以永久保存数据===》人的笔记本
输入设备
键盘
输出设备
显示器
2、看图总结:https://images2018.cnblogs.com/blog/1036857/201803/1036857-20180314171523158-1421724255.png
2.1、cpu存取的数据和指令都来自于内存
2.2、内存称之为主存
主存储器内的数据则是从输入单元所传输进来!而CPU处理完毕的数据也必须先写回主存储器中,最后数据才从主存储器传输到输出单元。
3、三大核心硬件
程序最先是存放于硬盘中的
程序的运行一定是先把程序的代码由硬盘加载到内存
然后cpu从内存中取出指令运行
4、什么是操作系统?为啥要有操作系统?
4.1、操作系统是一个协调、管理、控制计算机硬件资源与应用软件资源的控制程序
它位于计算机硬件与应用软件之间,起承上启下的作用
4.2 操作的系统意义
I:控制计算机硬件的基本运行
II:将硬件操作的复杂细节封装成简单的接口来提供给应用程序或用户使用
5、计算机体系的三层结构
应用程序、用户
操作系统
计算机硬件
6、平台与跨平台
平台具体指的是应用程序的运行平台,或者说用户的使用平台
平台=操作系统+计算机硬件
# 计算机基础知识想详解
1、cpu详解
cpu的分类与指令集
x86-64(*****)
cpu具有向下兼容性
64的cpu既能运行32位的程序也能运行64位的程序
内核态与用户态(*****)
代表cpu的两种工作状态
1、内核态:运行的程序是操作系统,可以操作计算机硬件
2、用户态:运行的程序是应用程序,不能操作计算机硬件
内核态与用户态的转换
应用程序的运行必然涉及到计算机硬件的操作,那就必须有用户态切换到
内核态下才能实现,所以计算机工作时在频繁发生内核态与用户态的转换
多线程与多核芯片
2核4线程:
2核代表有两个cpu,4线程指的是每个cpu都有两个线程=》假4核
4核8线程
4核代表有4个cpu,8线程指的是每个cpu都有两个线程=》假8核
2、存储器
RAM:内存
ROM:“只读内存”
存放计算机厂商写死计算机上的一段核心程序=》BIOS
CMOS:存取速度慢,断电数据丢失,耗电量极低
硬盘:
机械硬盘:磁盘
磁道:一圈数据,对应着一串二进制(1bit代表一个二进制位)
8bit比特位=1Bytes字节
1024Bytes=1KB
1024KB=1MB
1024MB=1GB
1024GB=1TB
1024TB=1PB
200G=200*1000*1000B
扇区:
一个扇区通过为512Bytes
站在硬盘的解读,一次性读写数据的最小单为为扇区
操作系统一次性读写的单位是一个block块=》8扇区的大小=4096Bytes
柱面
固态硬盘
IO延迟(*****)
7200转/min
120转/s
1/120转/s=转一圈需要花费8ms
平均寻道时间:机械手臂转到数据所在磁道需要花费的时间,受限于物理工艺水平,目前机械硬盘可以达到的是5ms
平均延迟时间:转半圈需要花费4ms,受限于硬盘的转速
IO延迟=平均寻道时间+平均延迟时间
优化程序运行效率的一个核心法则:能从内存取数据,就不要从硬盘取
虚拟内存
IO设备=设备的控制+设备本身
3、总线
4、操作系统的启动流程(*****)
BIOS介绍:
BIOS:Basic Input Output System
BIOS被写入ROM设备
裸机:
cpu
ROM:充当内存,存放BIOS系统
CMOS:充当硬盘
操作系统的启动流程(*****)
1.计算机加电
2.BIOS开始运行,检测硬件:cpu、内存、硬盘等
3.BIOS读取CMOS存储器中的参数,选择启动设备
4.从启动设备上读取第一个扇区的内容(MBR主引导记录512字节,前446为引导信息,后64为分区信息,最后两个为标志位)
5.根据分区信息读入bootloader启动装载模块,启动操作系统
6.然后操作系统询问BIOS,以获得配置信息。对于每种设备,系统会检查其设备驱动程序是否存在,如果没有,系统则会要求用户按照设备驱动程序。一旦有了全部的设备驱动程序,操作系统就将它们调入内核
BIOS
1、存有win10系统的光盘、u盘、移动硬盘:无密码
2、本地硬盘上的win7系统:密码
应用程序的启动流程(*****)
1、双击exe快捷方式--》exe文件的绝对路径,就是在告诉操作系统
说:我有一个应用程序要执行,应用程序的文件路径是(exe文件的绝对路径)
2、操作系统会根据文件路径找到exe程序在硬盘的位置,控制其代码从硬盘加载到内存
3、然后控制cpu从内存中读取刚刚读入内存的应用程序的代码执行,应用程序完成启动
# python入门(全为重点)
1、编程语言介绍
分类:
机器语言
汇编语言
高级语言(编译型、解释型号)
总结:
#1、执行效率:机器语言>汇编语言>高级语言(编译型>解释型)
#2、开发效率:机器语言<汇编语言<高级语言(编译型<解释型)
#3、跨平台性:解释型具有极强的跨平台型
2、python介绍
python语言:指的是pyton的语法风格
python解释器:专门用来识别python这门语言的语法并解释执行的
3、解释器多版本共存
设置环境变量
windows
win10:参考视频
win7:C:\python27;C:\python27\scripts;C:\a\b;D:\a\b;E:\a\b
linux:
vim /etc/profile
PATH=$PATH:/usr/local/python38:/usr/local/python38
export PATH
mac:
同linux
4、运行python程序的两种方式
1、交互式
即时得到程序的运行结果,多用于调试
2、脚本的方式
把程序写到文件里(约定俗称文件名后缀为.py),然后用python解释器解释执行其中的内容
python3.8 python程序文件的路径
5、一个python应用程序的运行的三个步骤(******)
python3.8 C:\a\b\c.py 执行python程序经历三个步骤
1、先启动python3.8解释器,此时相当于启动了一个文本编辑器
2、解释器会发送系统调用,把c.py的内容从硬盘读入内存,此时c.py中的内容
全部为普通字符,没有任何语法意义
3、解释器开始解释执行刚刚读入内存的c.py的代码,开始识别python语法
对比文本编辑器读取C:\a\b\c.py文件内容也经历了三个步骤
1、先启动文本编辑器
2、文本编辑器会发送系统调用,把c.py的内容从硬盘读入内存
3、文本编辑会将刚刚读入内存的内容控制输出到屏幕上,让用户看到结果
总结:
二者在前两个阶段做的事情完全一致
唯一不同的就是第三个阶段对读入内存的python代码的处理方式不同
6、注释
1、注释是对关键代码的解释说明
单行注释:#
# 这是一行xxx的代码
print("hello") # 这是一行xxx的代码
多行注释:'''''' """"""
"""
笔记
"""
2、被注释的代码不会被执行
7、IDE集成开发环境pycharm
mac平台pycharm使用参考视频讲解
windows平台pycharm使用参考博客https://zhuanlan.zhihu.com/p/108676916
windows平台下相关配置
选择pycharm对话框左上角File,然后点击settings,接下来的配置同mac平台
```
一、什么是变量?
变量就是可以变化的量,量指的是事物的状态,比如人的年龄、性别,游戏角色的等级、金钱等等
二、为什么要有变量?
为了让计算机能够像人一样去记忆事物的某种状态,并且状态是可以发生变化的
详细地说:
程序执行的本质就是一系列状态的变化,变是程序执行的直接体现,所以我们需要有一种机制能够反映或者说是保存下来程
三、如何用变量
'''
1、变量基本使用
原则:先定义,后引用
name = '' # 定义-》存
print(name) # 引用-》取
age = 18
print(age)
2、内存管理:垃圾回收机制
垃圾:当一个变量值被绑定的变量名的个数为0时,该变量值无法被访问到,称之为垃圾
引用计数增加
x = 10 # 10的引用计数为1
y = x # 10的引用计数为2
z = x # 10的引用计数为3
引用计数减少
del x # 解除变量名x与值10的绑定关系,10的引用计数变为2
print(y)
del y # 10的引用计数变为1
print(z)
z = 12345 # # 10的引用计数变为0
print(z)
3、变量有三大组成部分
I:变量名=》是指向等号右侧值的内存地址的,用来访问等号右侧的值
II:赋值符号:将变量值的内存地址绑定给变量名
III:变量值:代表记录的事物的状态
4、变量名的命名的规则
原则:变量名的命名应该见名知意
4.1. 变量名只能是 字母、数字或下划线的任意组合
4.2. 变量名的第一个字符不能是数字
4.3. 关键字不能声明为变量名,常用关键字如下
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from','global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
age=18
print='Harry'
ps:不要用拼音,不要用中文,在见名知意的前提下尽可能短
mingzi='Harry'
名字='Harry'
print(名字)
5、变量名的命名风格
5.1 纯小写加下划线的方式(在python中,关于变量名的命名推荐使用这种方式)
age_of_alex = 73
print(age_of_alex)
5.2 驼峰体
AgeOfAlex = 73
print(AgeOfAlex)
6、变量值三个重要的特征
name='egon'
id:反映的是变量值的内存地址,内存地址不同id则不同
print(id(name))
type:不同类型的值用来表示记录不同的状态
print(type(name))
value:值本身
print(name)
6.2 is与==
is:比较左右两个值身份id是否相等
==:比较左右两个值他们的值是否相等
'''
id不同的情况下,值有可能相同,即两块不同的内存空间里可以存相同的值
id相同的情况下,值一定相同,x is y成立,x == y也必然成立
>>>
>>> x='info:Egon:18'
>>> y='info:Egon:18'
>>> print(x,y)
info:Egon:18 info:Egon:18
>>> print(id(x),id(y))
4565819264 4566192176
>>>
>>>
>>>
>>> x == y
True
>>> x is y
False
'''
了解:小整数池[-5,256]
从python解释器启动那一刻开始,就会在内存中事先申请
好一系列内存空间存放好常用的整数
'''
>>> m=10
>>> n=10
>>> id(m)
4562619328
>>> id(n)
4562619328
>>>
>>> res=4+6
>>> res
10
>>> id(res)
4562619328
'''
'''
>>> x=-5
>>> y=-5
>>> x is y
True
>>> x=-6
>>> y=-6
>>> x is y
False
'''
'''
>>> x='aaa'
>>> y='aaa'
>>>
>>>
>>> id(x)
4566200880
>>> id(y)
4566200880
'''
'''
x=-6
y=-6
print(id(x))
print(id(y))
print(x is y)
'''
7、常量:不变的量
注意:python语法中没有常量的概念,但是在程序的开发过程中会涉及到常量的概念
AGE_OF_ALEX = 73 # 小写字母全为大写代表常量,这只是一种约定、规范
AGE_OF_ALEX = 74
print(AGE_OF_ALEX)