编程语言的本质:'语言',语言的本质是沟通交流的工具
自然语言(汉语,日语,汉语)-->人和人之间进行沟通交流的工具
编程语言(python,Java,c)-->人和计算机之间进行沟通交流的工具
说人话:程序员用一种电脑能理解的方式,和它沟通,下达指令
代码/指令:
人类饿了,就会说'我饿了' 表达自己想吃饭
现在说了句'了我饿',好像听不太懂,似懂非懂,帮你自动扳回来,能勉强看懂,但是计算机不能-->电脑很蠢,是不能自动优化错误,所以我们的语法要正确
学习编程,说白了就是学习怎么和电脑进行沟通,只要指令能让计算机听懂,就都会按照你说的
1.机器语言: 最古老的编程语言 指令0/1,又称机器码
编程语言的由来,是基于晶体管(日光灯,只有两种行为 开关 对应的是1和0)
二进制-->0和1
八进制--> 0-7
十进制-->0-9
十六进制-->0123456789abcdef
计算机最底层是通过二进制来处理数据
2.汇编语言
因为二进制的理解难度太大了.所以在二进制的基础上衍生出来汇编
把一些常用的操作 用单词(助记符)来代替
在原有机器码基础上优化了,但整体理解起来还是有点变态.
3.高级语言
更加符合人类语言习惯
人类: 陌上说:'我饿了'
python: print('我饿了')
print 相当于 人类<说>的意思
高级语言就是用人类的思维去写代码
高级语言之母-->c语言-->c不是第一个语言,是因为很多高级语言的特性都事从C 才开始有的
学python要有自信-->python是高级语言里面算非常简单易学的 代码量也相对较少
为什么要安装Python:python是一个运行环境,如果要写.执行py程序都要用它
1.Python在哪下载:
官网下载(python.org)-->服务器在国外,访问比较慢
2.python大版本的区别:
python有两个大版本,python2和python3
python2是比较老的.现在统一用python3
版本需要3.8 以上就OK
安装python:
python是一个环境,不是应用程序,所以python下载成功后不会带有图标,装完之后只是多出来一个程序
卸载python:uninstall
3.环境变量(path):作用是让电脑认识python,以后能够访问,识别到python
4.进入cmd的步骤
win键+r键-->输入cmd-->按下回车
cmd-->终端/命令控制台,可以在里面执行一些命令
5.怎么判断python是否安装好
1.打开cmd,输入where python 回车键 显示python安装位置
2.打开cmd,输入python 回车键 进入python环境
6.打开idle的步骤:
1.按下win键
2.找到python软件
3.找到idle
4.右键-->更多-->打开文件所在位置
5.直接复制/拖拽到桌面(或者右击选择添加到桌面快捷方式)
调整字体大小:options--Configure IDLE--size
人类沟通有两种常见的行为
1.说话(输出) 把你想说的直接说出来
2.写字(输入) 把你想表达的东西 先'写下来'给别人看
1.用print说话/让python输出一句话-->print输出语句
语法规则:
print(内容) #如果要打中文/字母需要加上引号,如果是纯数字就不用 还有所有的符号都要是英文状态下的符号
实例:
print('大家好,我是陌上')
print(123)
2.用input写字/让python输入一句话-->input 输入语句-->一问一答
让python接收你在键盘里的输入
语法规则 :
input('提醒内容') #程序运行后,会暂停运行,等待你输入内容完成并按下回车之后才继续执行
实例:
正确用法
input('请问你叫什么名字')
input('请输入你的密码')
错误实例:
input('我的密码是123456')
input() #不知道要输入什么东西 没有提醒内容
常见的错误:
1.用了中文标点符号(python是外国人发明的,所以符号也要用英文)
2.print和input不要大写
3.input括号里的内容,是提醒内容,提醒用户这里应该输入什么,而不是把结果放进来
4.不要漏写符号(比如引号,括号)
python有两种开发模式:
1.交互模式-->进入python环境/默认打开idle就是交互模式,表示形式为>>>
类似于人类说话,说错话就好比覆水难收,改不回来了,所以代码输入错了不能修改
优点:用起来比较方便,即问即答,适合测试一些小代码
缺点:不能修改,不能保存
2.脚本模式(文件模式)-->新建一个文件来写代码,写好的代码可以保存起来反复使用,也可以修改
正常写代码都是用脚本模式
优点:可以保存,可以修改
在idle中如何新建文件:
快捷键 ctrl+n
file-->new file-->按下ctrl+s保存
保存文件时,要选择:1.文件名 2.文件保存位置
打开文件:file-->open
运行程序快捷键是F5
run -->run module
提个东西:
交互模式中input输入的内容会打印,但脚本模式不会,这也是他们两个的小区别
还有交互模式中>>>后面可以直接跟上你测试的小代码 比如>>>'hello'
注释相当于说明文档,说明使用,让别人或者你自己看代码的时候 可以更好的理解相关含义
因为注释是给开发人员看的,不会参与程序运行
python有两种注释方式:
1.单行注释-->用#符号表示,在#后面的内容都是注释
# 注释内容
例:
#这里是输出语句
print(456)
2.多行注释-->用一对三引号包裹着的内容(三对引号=单双都OK)
'''
不要删我
要不然我会报错
因为我是多行注释
我在里面说多少
都不会执行
你看着吧
'''
print('我是**功能代码')
'''
我这里面都事注释
你写多少度不会执行
'''
注释还有一种使用情况,有一段代码,不想执行它,但是也不想删除,就可以把他先注释
学习阶段时,养成写项目规范的习惯,对后续有帮助
'''
项目名称:
项目描述:
项目环境:
作者所属:
'''
生活中有什么是可以改变的量---钱,余额,发际线
计算机中的变量,他也是可变的量,因为他可能是一个字符串,一个数字或者一个小数
变量--数据的容器,存数据-->计算机的本质就是跟各种数据打交道
编程中有很多的数据可能会反复使用,每次都要去重写很蠢,所以就把他保存起来,取个好理解的名字,要用的时候直接调用名字就可以了
在计算中我们的变量是由3个东西组成
1.数据类型(type)
2.内存地址(id)
3.值(value)
可以把变量想象成一个仓库
数据类型-->仓库类型
内存地址-->仓库地址
变量值-->仓库里放的东西
变量名(标识符)的命名是有规则的,规范的
夏88-->不合法
夏%$^$%&-->不合法
夏人民币-->有特别含义
变量名也有规则规范
变量名命名规范:
1.一般是由数字,字母,下划线组成(中文可以,但不要去这样命名)
2.首字符不能是纯数字,不能数字开头
3.符号只能用下划线,不能用其他符号
4.变量名区分大小写 Name name
5.不要用python中有特别含义的名字--关键字/内置函数
print,input
如何查看关键字
import keyword
print(keyword.kwlist)
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
6.见名知意-->一眼看得出来,这个数据是干嘛的
name 姓名 age 年龄
一定要注意变量以及注释的规范性-->确保代码的可读性
因为在项目开发的时候,大部分时间其实不是在敲代码,而是在看代码
1.声明变量:把右边的数据赋值给左边的变量名
语法格式:
变量名=变量值
实例:
name='陌上' #记得中文或者字母都要有引号
age=18
声明多个变量,用逗号隔开
语法格式:
变量名,变量名=变量值,变量值
实例:
money,hometown=6.66,'陕西西安'
2.使用变量:直接输出变量名
语法格式:
print(变量名)
实例:
#如果变量加了引号的话,就变成了字符串了
print(name) #注意直接打变量名就可以了,不要加引号
print('name') #打印出来的是name,而不是陌上
输出多个变量是,用逗号隔开
语法格式:
print(变量名,变量名)
实例:
print(money,hometown,age)
3.给input用变量赋值
语法格式:
变量名=input() #会把用户输入的数据赋值给一个变量
例:
name1=input('请输入你的名字')
print(name1)
注意:先定义变量,再使用变量
生活例子:
智能垃圾分类为:可回收,有害垃圾,其他垃圾...
为什么要分类垃圾?
为了更方便的处理 更方便
所以也要区分数据的类型
那区分数据目的:数据分这么多类型,是因为在开发中,会使我们更方便的运用和操作管理数据
有一个功能函数,可以获取一个数据是什么类型的
语法格式:
type(变量)
type(数据)
实例:
age=18
print(age)
print(type(age))
print(type(18)) #一次只能放一个
整数 没有小数点的数 520 80 -1 -800
用来帮助我们存储一些整数数据:人数,年龄
声明方式:变量名=整数值
实例:
age=18
print(age)
print(type(age))
浮点数 带有小数点的数 0.8,6.66,2.0
用来帮助我们存储一些浮点数据:身高,体重
声明方式:变量名=浮点值
实例:
money=6.6
print(money)
print(type(money))
print(type(0.0))
True 真 1
False 假 0
布尔类型主要是用来做判断的一种类型 用True表示真 用False 表示假
print(1+1>2) #False
print(1+1>1) #True
声明方式:
变量名=True
变量名=False
is_login=True
is_vip=False
细节:
一定要记住单词首字母大写(True,False)
str 字符串-->保存一些字符(汉字,数字,字母,符号)-->姓名,地址,菜单
表现形式为:用一对单/双引号包裹起来的数据 用来保存一行字符串
用三对单/双引号包裹起来的数据 用来保存多行内容
定义方式:
变量名='字符串'
变量名='''
多行文本
多行文本
'''
实例:
name='陌上'
poem='''
醉里挑灯看剑,
梦回吹角连营。
'''
print(name)
print(poem)
引号不能混用
实例:
print('陌上") #会报错
单双引号嵌套的使用
错误实例:
print('陌上说:'你真帅',现在我还能打印吗') #不能识别到你哪一对是一对
正确实例:
print("陌上说:'你真帅',现在我改回来了,不是一样的引号可以打印吗")
字符串支持*号输出,原理是把字符串复制N遍
print('好好学习'*10)
字符串拼接是通过+号,但前提是双方都是字符串 #这个+号是拼接的意思,而不是数学的加号
print('好好学习'+'天天向上')
#print('好好学习'+1) #这个会报错,我们不是同类人,不支持两者拼接
int float bool-->数值类型,表示一个数值,数值类型比较适合存储一个数据,不适合存储多个数据,数值类型没有下标的概念
要存储多个数据的话其实可以用序列类型存储
序列类型:
1.可以存储多个数据的一种类型
2.里面的数据是有顺序,坐标概念的
在序列类型中数据都是有下标的概念
下标类似于坐标,比如酒店的房间/宿舍门牌号
在程序中,和生活习惯不一样,程序下标是从0开始计算的
人类报数:1 2 3 4 5 ;第一个数是1,第二个数是2
机器报数:0 1 2 3 4 ;第一个数是0,第二个数是1
下标也支持负数取值,最后一个数为-1,倒数第二个数为-2
name='陌上真帅'
陌 上 真 帅
0 1 2 3
-4 -3 -2 -1
我们现在知道了一个数据所在的位置,是不是也可以找到这个数据,并且把他提取出来
在序列类型中,通过下标提取对应的一个数据,这种行为称为索引
语法:
序列名[下标]
实例:
name='陌上许总'
print(name[0]) #陌
print(name[2]) #许
print(name[-2]) #许
print(name[6]) #报错,下标越界
索引可以取出来数据,但是一次只能提取一个数据,如果需要提取多个数据就很麻烦,这时就可使用切片
在序列类型中,通过下标一次性提取多个数据的行为,这种行为称为切片
语法:
序列名[起点:终点] #终点实际到他的前一位
实例:
talk='今天我们也要好好学习呀'
print(talk[0:3]) #今天我 终点是前一位 3的前一位是2这个下标的数据
print(talk[2:6]) # 我们也要
print(talk[2:20]) # 超出范围的索引,切片操作是不会报错 他就只是默认帮你取完 我们也要好好学习呀
print(talk[1:]) #终点不写,从1开始取完 天我们也要好好学习呀
print(talk[:5]) #起点不写,默认从0开始取 今天我们也
print(talk[-1:]) #呀
print(talk[-5:-2]) #好好学
print(talk[2:-2]) #我们也要好好学
切片的细节:
1.切片时,终点值实际都是取到他的前一位,比如写2:6,实际取得是2:5
2.切片是,起点值和终点值可以空着不写,不写起点的话默认从0开始取,不写终点,默认取到最后
3.切片 超出索引不会报错,那默认就是取完,跟单独索引不样,单独索引超出下标会报错
生活中有的人腿很长,走楼梯一次走2,3格
程序中, 正常取数据都是一位位的取,步长为1,可以通过设置步长的方式
取数据跨位取,但是这个跨位是有规律的
语法:
序列名[起点:终点:步长]
实例:
num='123456789'
print(num[2:6]) #正常取2:5的数据 3456
print(num[::2]) #去全部数据 一次隔两位取 13579
print(num[::-1]) #取全部数据 反向输出
其实一般用到最多的就是print(num[::-1]) 反向输出的操作
之前学的数据类型都比较单一
要么纯数字/小数/字符
如果想把他们都放在一起保存,就需要接下来这两种序列类型:
列表/元组
列表(list):表示形式为用一对中括号包裹起来的数据,里面的数据用逗号隔开
列表可以存储几乎所有的数据,并且里面的数据可以修改
语法:
列表声明:
列表名=[数据1,数据2,数据3]
列表修改:
列表名[下标]=数据 #修改指定下标的数据
实例:
question=['在吗',10,False,1.5]
print(question)
question[0]='列表怎么声明'
question[2]=True
print(question)
列表还可以嵌套.也就是说列表里面还可以放列表
a=[1,2,3]
b=[4,5,6]
c=[a,b]
print(c)
print(c[0]) #取出列表a
print(c[0][1]) #取出列表a,再取出a里面的元素2
元组(tuple):表示形式为用一对小括号包裹起来的数据,里面的数据用逗号隔开
里面的数据不可以修改
语法:
元组声明:
元组名=(数据1,数据2,数据3)
实例:
teacher=('李震','应江奔','许叶彤')
print(teacher)
print(type(teacher))
print(teacher[1])
#teacher[1]='tt' #元组不支持修改 会报错
如果你要存的数据,会被修改-->用列表
food=['辣椒炒肉',15,'香干炒肉',25.5]
如果你要存的数据,不会被修改-->用元组
size=('s','m','l','xl')
teacher=('李震','应江奔','许叶彤')
在python中特别功能的一些'字符' 表示形式为\后面加了指定的字符
\n --换行
\t --制表符 4个空格 tab
\ --正常输出斜杠\
' --正常输出引号
实例:
print('好好学习\n天天向上') #我是换行
print('好好学习\t天天向上') #我是制表符
print('好好学习\天天向上') #正常输出一个斜杠符号
print("好好学习'天天向上") # 正常输出一个引号
print('好好学习\'天天向上') #正常输出一个引号,如果说有一样的引号会报错 那你加转义\就可以了
如果有个字符串里面有很多 但是并不是要用的转义字符 可以在他前面加上r 取消转义
实例:
print(r'好好学习\n天天向上')
主要用于网站/电脑文件的
实例:
test1='D:\tproject\__pycache__\node'
test1='D:\tproject\__pycache__\node'
test2=r'D:\tproject\__pycache__\node'
print(test1)
print(test2)
转义字符用的最多的就是
\n 和\t 以及前面加个r取消转义
需要了解更多转义字符的可以来这里面查询并且使用:http://c.biancheng.net/view/2176.html
在程序开发时,有时候需要涉及到数据之间的相互转换
字符串'88',转为数值
数值88,转为字符串
所以针对这个情况,就可以通过类型转换来实行
但是有个前提,操作数据必须得合法规范
一次只能转一个数据
int(数据) -->把数据转换为整型
int('88')
float(数据) -->把数据转换为浮点型
bool(数据) -->把数据转换为布尔型
str(数据) -->把数据转换为字符串型
list(数据)-->把数据转换为列表型
tuple(数据) --> 把数据转为元组型
咱们input得到的数据都是字符串类型
age=input('请输入你的年龄')
print(age)
#input得到的数据都是字符串类型
print(type(age)) #字符串
#print(age+1) #报错 字符串不能和整型相加
如果要实现得到的input输入后的内容是int类型,这么写
age=int(input('请输入你的年龄'))
print(age)
#input得到的数据都是字符串类型
print(type(age)) #int
print(age+1) #年龄+1
类型转换后之后,如果你需要用转换之后的这个数据,那就要重新赋值,
age2='18'
print(type(age2)) #str
age2=int(age2) #做法一重新赋值给原变量age2
print(type(age2)) #这个时候age2就是int类型了
print(age2+1)
age3=int(age2) #做法二也可以用新的变量接收
print(age3+2)
注意
在python中,给变量命名是 不要取名为 int float print type
还有不要出现这种情况
str=xxx
int=xxx
float=xxx
list=xxx
tuple=xxx
球球了 不要这样做
这样是错误的 不要 这么写 写简写
list-->简写为li
name='陌上'
age=18
#print('大家好,我叫'+name+'我今年'+age+'岁了') #报错,int和str类型不能拼接
print('大家好,我叫'+name+'我今年'+str(age)+'岁了') #转换类型后可以输出,但是太麻烦
print('大家好,我叫',name,'我今年',age,'岁了') #虽然说有逗号隔开,但是每次还得考虑,也很麻烦
开发的时候 你每次开发一个东西 你还得考虑他的类型 然后就需要去注意 就很麻烦 而且还很容易出错
在以后写代码的过程中,经常会涉及到字符串和其他类型的变量在一起使用的环节,但如果变量不是纯字符串,而是int/float/其他类型的数据,拼接起来就很容易出错
比较low,麻烦的也就是字符串和字符串拼接:
字符串与字符串之间用+号进行拼接
字符串+字符串
name='陌上'
print('多喝'+'热水')
print('我是'+name)
所谓格式化-->一种更好的输出方式
1.可以让你更方便的输出带有变量的数据
2.可以让你更方便的输出一些固定格式的数据
尊敬的xx您好,您X月的账单已经发送,您使用话费共XX元
1.有标准格式
2.里面X都可以变量来代替
f-str(format string 全拼)
语法:在字符串前面加f/F,在字符串里把要输出的变量,用{}大括号包裹起来
f'xxx{变量}yyy'
print(f'大家好,我是{name},我今年{age}岁了')
大括号里的变量也是可以操作的,可以进行数值运算,切片,索引,方法
print(f'大家好,我是{name[1]},我今年{age+10}岁了')
我要请客吃饭,我不确定还有没有位置,我就先打个电话给酒店.--'预订'个包间
占位符概念-->先占个位置,后续再用具体的数据来顶上
形参:没有具体的数据,只是先占个位置--角色
实参:有具体的数据,在运行是取代形参--演员
仙剑奇侠传:
李逍遥 --有这样一个角色 是谁来演还不知道
胡歌--开拍之后才知道,是胡歌出演,在演戏的时候,胡歌就是顶替了李逍遥的位置,他从此就是李逍遥了
语法:
'xx%sxx'%数据
'xx%sxx%d'%(数据1,数据2)
%s str类型 --给 字符串占位置 后续来的数据是字符串
%d int类型 --给 整型占位置 后续来的数据是整型
%f float类型 --给 浮点型占位置 后续来的数据是浮点型(默认6位小数)
%.1f -->带一位小数
%.2f -->带两位小数
%.xf -->带x位小数
实例:
name='陌上'
age=18
print('我是%s'%'陌上') #实参可以是具体的数据
print('我是%s'%name) #实参也可以是定义的变量
print('我是%s,我今年%d岁了'%('陌上',age))
print('我是%s,我今年%d岁了,我现在还剩%f元'%('陌上',age,88.88)) #带六位小数
print('我是%s,我今年%d岁了,我现在还剩%.1f元'%('陌上',age,88.88)) #带一位小数
小细节:
%除了可以放变量,也可以直接放数据
放的都是已知数据,类型是固定死的
#print('我是%s,我今年%d岁了,我现在还剩%.1f元'%('伊诺','我要搞事了',88.88)) #%d是给整型占位置 你要传字符串就报错
一个位置一个坑,少了位置和多了位置都是不可以的
%s的包容性比较强,后续如果你来的数据是整型,浮点型,列表,元组,都可以接受
但是%d,%f确不行,必须来对应的数据
用法跟占位符,f-str类似,他先用大括号作为占位符,在字符串后面通过.format来传递数据
语法:
'xx{}xx'.format(数据)
'xx{}xx{}'.format(数据,数据)
'xx{下标}xx{下标}'.format(数据,数据)
实例:
name='陌上'
age=18
print('我是{},我今年{}岁'.format(name,age))
print('我是{},我今年{}岁'.format(name,19))
print('我是{},今天是{},我在马路边捡到{}元'.format('刘水','星期四',100))
print('我是{},今天是{},我在马路边捡到{}元'.format('星期四','刘水',100))
#大括号里的内容,也可以通过下标决定输出数据
print('我是{0},今天是{1},我在马路边捡到{2}元'.format('刘水','星期四',100))
print('我是{1},今天是{0},我在马路边捡到{2}元'.format('星期四','刘水',100))
#你要么放下标就全放,要么就都不放下标,如果只放部分下标就会报错
print('我是{1},今天是{},我在马路边捡到{}元'.format('星期四','刘水',100))
#print('我是{1},今天是{0},我在马路边捡到{3}元'.format('星期四','刘水',100)) #超出下标会报错
#结合循环遍历,做一个有仪式感的群发
names1=['尹天浩','刘绪国','卢泽宇','李震','应江奔','许叶彤']
for i in names1:
print('''
{}年快乐,{}在这里,祝{}端午节安康
身体健康,万事如意,多吃粽子
{}
'''.format('兔','陌上',i,'陌上'))
#优化一下代码
names2=['尹天浩','刘绪国','卢泽宇','李震','应江奔','许叶彤']
for i in names2:
print('''
{0}年快乐,{1}在这里,祝{2}端午节安康
身体健康,万事如意,多吃粽子
{1}
'''.format('兔','陌上',i))
跟数学优先级一样 (先乘除后加减)
+ | 加 |
---|---|
- | 减 |
***** | 乘 |
/ | 除 (得到的结果为浮点型) |
% | 取余 |
// | 整除 |
****** | 幂(乘方) |
这里讲运算符代码时为了方便快速测试用的交互模式,我省略了print
>>> 10%3
1
>>> 3**3
27
>>> 10//3
3
>>> 20//4
5
>>> 18//3
6
>>> 18//5
3
>>> 3**8
6561
>>> a=1
>>> b=1
>>> a+b
2
赋值符号的左边必须是一个变量名
需要赋值给谁就把谁放在最左边
= | 赋值运算符 | c = a + b(赋值运算符的程序是从右往左执行) |
---|---|---|
+= | 加赋值 | a+=b = = > > a=a+b |
-= | 减赋值 | a-=b= = > > a=a-b |
*= | 乘赋值 | a* =b= = > > a=a *b |
/= | 除赋值 | a/=b= = > > a=a/b |
%= | 取余 | a%=b= => > a=a%b |
//= | 整除 | a//=b= => > a=a//b |
* *= | 幂 | a* *=b= => > a=a * * b |
>>> a=1
>>> b=1
>>> a+b
2
>>> a+=b
>>> a
2
>>> b-=a
>>> b
-1
>>> a*=b
>>> a
-2
得到的结果为bool类型
在python中.一个等号是用来赋值,两个等号才是判断是否相等.
> | 大于 |
---|---|
< | 小于 |
== | 等于 |
>= | 大于等于 |
<= | 小于等于 |
!=(英文符号) | 不等于 |
>>> 66<88
True
>>> 34>500
False
>>> a=88
>>> b=66
>>> a>b
True
>>> b<=a
True
>>> a!=b
True
>>> a==b
False
得到的结果为bool类型
代码 | 含义 |
---|---|
and | 与 and左右两边的值必须都为真的时候才为真,否则为假 – >‘和’ |
or | 或 or左右两边的值其中有一个真即为真,全假才为假 – >‘或’ |
not | 非 就是将值为真的变成假的 假的变成真的 – >‘非’ 取反. 死杠精什么东西都和你反着来 |
父母:python大于95,math大于90,两名达到要求,可以吃大餐,否则混合双打
>>> python=98
>>> math=70
>>> python>=95 and math >=90
False
>>> python>=95 or math >=90
True
>>> python>=100 or math >=90
False
>>> python>=95 and math >=60
True
>>> not True
False
>>> not False
True
得到的结果为bool类型 序列类型有字符串,列表,元组
代码 | 含义 |
---|---|
in | 判断成员是否在序列中 |
not in | 判断成员是否不在序列中 |
>>> talk='陌上很帅'
>>> '丑' in talk
False
>>> '美' in talk
False
>>> '丑' not in talk #判断丑不在talk 里
True
>>> '美' not in talk
True
符号 | 描述 |
---|---|
() | 小括号 |
** | 幂(乘方) |
*、/、//、% | 算术运算符 |
+、- | 算术运算符 |
<、>、<=、>=、==、!= | 比较运算符 |
in、not in | 成员运算符 |
not > and > or | 逻辑运算符 |
短路运算符,代码在判断时,已经知道结果了,后面的判断就不会执行
假设我现在有一根电线,a、b、c三个点分别代表这个电线上三个非常关键的连接点,电流的方向是这样的
a------->b--------c>
如果a短路了,b和c肯定没电,如果b短路,电流会正常经过a,但是c不能,如果c短路,电流会正常经过ab
and:当前面的值为假时,and后面的值不会执行
>>> 0 and 1
0
>>> 1 and 0
0
or:当前面的值为真,or就不会往后面执行
>>> 0 or 1
1
>>> 1 or 0
1
pycharm是python圈子里最受欢迎的开发工具
ide -->集成开发环境 -->有很多功能的作案工具
编辑器 -- 让你写/改代码的地方
编译器 -- 帮你运行代码的工具
调试器 -- 帮你测试,调试bug的工具
杂七杂八 -- 远程连接工具,虚拟机工具,git工具
pycharm有两个版本:
1.专业版 -- 要钱,功能多点
2.社区版 -- 免费,功能少点
pycharm有中文汉化包 -->plugins里搜索Chinese下载可以使用 -->但是不推荐用,尽量还是用英文版
下载官网:
1.官网 https://www.jetbrains.com/zh-cn/pycharm/download/#section=mac
pycharm安装好之后不要随便移动更改位置!!!!也不要更新pycharm
项目文件也不要随意拖动改位置
新建python文件:
选中项目文件夹 -- 右键 -- new -- python file -- 输入文件名 -- 回车
设置字体大小 -- file -- setting -- 搜索font -- 修改大小
运行程序 -- 编辑器右击 -- run
设置主体颜色:-- file -- setting --Appearance--Theme
Darcula 黑色
pycharm快捷键
1.快速注释代码 --> 选中代码行 -->Ctrl+/(取消注释也一样)
2.快速复制上一行代码 --> 选中代码行 -->Ctrl+d
打开python文件项目:
file-->open-->找到你想要打开的文件就可以打开了
为什么双击程序没有反应
写好了一个python文件,保存之后,要运行他直接双击了,但是你看起来没反应
昙花一现--> 有个花叫昙花,开花的一瞬间很美很漂亮,但是很短暂,稍纵即逝
当你双击程序后,程序其实运行了-->快速启动 快速运行 运行完后光速暴毙 没有留下痕迹
所以如果要程序运行 并且想要看到他的运行结果最好是用上工具
1.用idle-->file-->open-->找到你要运行的python文件打开-->运行
2.用pycharm运行 file-->open-->找到你要运行的python文件打开-->运行
编程语言:人和计算机沟通交流的额方式,通过写代码的方式控制电脑实现特定的功能
输入输出(Io)语句
print:输出函数 输出一句话
语法:print(数据) #如果是数字或者变量你可以直接放,如果是字符(字母,中文,符号)要加引号
input: 输入函数 接收用户输入的结果内容
语法:input(提示内容) #重点 括号内的不是结果而是提醒用户这里需要输入时什么内容 再随着运行用户输入内容
input('请输入你的名字') #运行时会先输出提醒内容,再进行输入操作
交互模式表示形式为>>> 简便但是不好保存 也只能测试一行小代码
脚本模式(文件模式) 方便修改 可以保存 正经写代码都是用脚本模式
程序员的自我修养(注释)
单行注释表示形式为:在文字/代码前面加#号
多行注释表示形式为:用三对引号包裹的数据 单双引号都OK
'''
项目名称:
项目描述:
项目环境:
作者所属
'''
变量:存储数据的容器 把一个数据保存起来取个名字方便后续使用
变量命名规范:
1.变量名由下划线,字母,数字组成
2.首字符不能是数字,也不能是纯数字
3.不能有奇怪的特殊符号(&%@^)
4.不要用特殊含义/关键字的词取名
再次球球你们了,不要给变量取名为 float,list,type,input,print,str,tuple
print=123
print('我还能打印吗') #报错
5.python里变量是区分大小写的
6.见名知意(大驼峰/小驼峰/链式命名)
看到这个名字就知道他是干嘛用的
提高代码阅读性
声明变量: 变量名=变量值 #age=18
使用变量: print(变量名) #print(age)
也可以给input用变量赋值(如果需要结果为其他类型需要转换)
数值类型: 不支持下标 索引 切片 步长等等操作
int 整型 没有小数点的数 #1 2 3 -1 age=18
float 浮点型 带小数点的数 #1.0,8.8 money=8.8
bool 布尔类型 主要用于判断 也可以作为数值运算
True/1/真 False/0/假
序列类型:
str 字符串 用一对引号包裹起来的数据,里面主要就是用来保存(字符,符号,汉字,英文,数字)
name='陌上' #这样的'1' 'True'也是字符串
list 列表 用一对[]中括号包裹起来的数据 数据之间用逗号隔开 里面什么都可以放 可以修改
info=['陌上',1,8.8,True]
tuple 元组 用一对()小括号包裹起来的数据 数据之间用逗号隔开 里面什么都可以放 但是不可以修改!!!
如果元组只有一个数据也要加逗号!!!
demo=('陌上',) #没加逗号 就是一个字符串类型
four_star=('刘德华','张学友','郭富城','黎明')
type功能函数 查询数据类型
print(type('1'))
序列类型的特性:
下标:坐标 所在位置(计算机下标从0开始计算)
好 好 学 习
0 1 2 3
-4 -3 -2 -1
索引:通过下标获取值(单个)
语法:序列名[下标]
four_star=('刘德华','张学友','郭富城','黎明')
print(four_star[2]) #'郭富城'
print(four_star[-2]) #'郭富城'
切片:通过起点/终点设置取一部分需要的数据,终点值是到他的前一位
语法:序列名[起点:终点]
print(four_star[2]) #'郭富城'
print(four_star[-2]) #'郭富城'
print(four_star[1:3]) #('张学友', '郭富城')
print(four_star[:3]) #('刘德华', '张学友', '郭富城')
print(four_star[:-1]) #('刘德华', '张学友', '郭富城')
步长:一次性跨位取或者取反
语法:序列名[起点:终点:步长]
print(four_star[::2]) #('刘德华', '郭富城')
print(four_star[::-1]) #('黎明', '郭富城', '张学友', '刘德华')
转义字符:在python中就是代表特比功能的'字符' --\
\n---换行
\t--制表符 tab(四个空格)
取消转义 字符串前面加r
talk='晚上好\n乡亲们\t我又回来了'
talk1=r'晚上好\n乡亲们\t我又回来了'
print(talk)
print(talk1)
格式化输出:可以更好更方便的输出带有变量的数据
f-str-->在字符串前面加上f,把输出的变量用大括号{}包裹qilai
name='贺天斌'
num=1
print(f'我叫{name},这是我第{num}次上电视')
占位符-->先用占位符占位置,后续再用具体的数据来顶上运行
%d-->占一个int类型
%s-->占一个字符串类型
%f-->占一个浮点类型
%.1f-->保留一位小数
%.xf-->保留x位小数
name=['陌上','LLL']
num=1
print(f'我叫{name[0]},这是我第{num}次上电视')
print('我叫%s,这是我第%d次上电视'%(name[1],num))
.format-->先用大括号占位置,后续再用实际的数据来顶上,对数据类型没有要求(如果大括号里面放下标的话,要么都放下标,要么都不放,如果只放部分下标就会报错)
name=['李白','王维','杜甫']
num=1
money=8.88
print(f'我叫{name[0]},这是我第{num}次上电视')
print('我叫%s,这是我第%d次上电视'%(name[1],num))
print('我叫{},这是我花{}元买的第{}次上电视,我出息了,我要赚{}万'.format(name[-1],money,num,100))
运算符:
算数运行算符:+加 -减 *乘 /除 %取余 //整除 **乘方
% 取余 10%3 -->1
10-3-3-3=1 最后剩下的是余数1
// 整除 10//3 -->3
10除3=3.33333 去掉后面的小数就是他的整除数,整除数为3
** 取幂 3**3 -->27 3的三次方
3*3*3
赋值运算符:= += -= /= %= //= **= #a=a+1.简写a+=1
比较运算符:> < == >= <= != #两个等号才是比较 一个等号是赋值 != 不等于
逻辑运算符:and #都为真才为真
or#一个为真就为真
not #你是真的就为假 你是假的就为真
成员运算符:in: 判断数据是否在序列里面
not in: 判断数据是否不在序列里面
编程语言通过运行的方式不同,分为主流两种性质的语言,一种叫解释型,一种叫编译型
有个老外 不懂中文 很想看三国演义的故事(1.没时间学中文 2,没有英文版的书)
1.找随身翻译-->陪着自己,要看的时候就问对方-->解释型
优点:
效果快 比较方便
缺点:
读起来慢,要听对方一句句翻译
有依赖性,必须得翻译官在 不在就gg
2.把整本三国演义,翻译成英文版-->编译型
优点:
读起来比较快,看起来很方便
不需要借助翻译,有书就行
缺点:
不好修改 如果有一页打错了必须整本打印
不够灵活
编译型:把代码转化为可执行文件再运行程序-->把你的代码,弄成一个.exe的文件
c/c++
优点:
效率比较快 性能比较好
不需要安装环境就可以运行
缺点:
不够灵活 修改起来比较麻烦 如果修改之后 要重新进行编译 重新生成一个可执行文件
解释型:安装一个解释器要运行程序的时候一行一行来解释执行 需要安装环境
python
优点:
更灵活 修改起来方便
兼容性更好 更好的跨平台 一段代码 要换到别的系统执行就直接换个解释器就可以了
缺点:
性能没有那么好 比较慢
运行程序正常情况下都需要依赖环境 不好做到脱离运行
书写规范 : code --Reformat code
红色波浪线:提醒可能报错
黄色波浪线:提醒书写不规范(code --Reformat code,就可以去掉黄线)
1.顺序执行:
程序执行时,代码从上往下执行,从左往右依次执行,中间如果有报错,后面的内容不再执行,如果遇到报错,后面的内容不再执行,终止程序
2.选择执行:
根据条件满足与否,执行对应代码--让你用如果/或者来造句
3.循环执行:
根据条件满足与否,循环执行对应代码--让你重复做一件事
上述提到这个满足与否,是通过布尔类型来判断
在python中,是通过缩进来表示一个代码块的权限
相当于缩进的代码,就是他的上一级代码(没缩进)的小弟,小弟听大哥的话
陌上:
应江奔 #这个加了缩进才是陌上的小弟
李震
许叶彤
精神小伙 #这个跟陌上平级
python 中,缩进是用一个tab(四个空格)来表示
num=20
if num>10:
print('我是你小弟,因为我加了缩进')
print('我是if外面的,没加缩进,我不归if管')
if语句的作用为'条件判断',根据判断结果执行对应代码
if:如果
else:否则
elif:或者
单分支:满足条件就执行对应if里的代码,不满足就无事发生
语法格式:
if 判断条件:
执行语句 #该代码执行,就是当if后面的判断条件成立是(True)就执行,否则就不执行
实例:
age=int(input('请输入你的年龄'))
if age>=18:
print('恭喜你成年了')
双分支语句:满足条件就执行if里的代码,否则不满足就执行else里的代码
语法格式:
if 判断条件:
执行语句 #如果满足if的条件,就执行if里的代码
else:
执行语句 #否则执行else里的代码
实例:
money=400
if money>=500:
print('我真有钱,富婆!!!')
else:
print('穷鬼')
多分支语句:满足条件就执行if里的代码,如果不满足if条件的代码,就接着往下判断elif的语句,满足elif的条件就执行elif里的代码,if和elif都不满足才会执行else里的代码
语法格式:
if 判断条件:
执行语句 #如果满足if的条件,就执行if里的代码
elif 判断条件:
执行语句 #如果if的代码不满足,才会执行到这,如果满足elif的条件,就执行elif的代码
else:
执行语句 #否则if和elif都不满足 就执行else里的代码
实例:
score=int(input('请输入你的考试成绩:'))
if score == 100:
print('吃大餐')
elif score>=80:
print('玩十分钟游戏')
elif score>=60:
print('再接再厉')
else:
print('男女混合双打')
elif可以有多个,一组里面if和else只能有一个
判断数字大小的条件 最好是由大往小去判断
if还有个特性 判断的条件有值就执行,否则就else里的代码
有值为真 没有值为假([],(),'',{},None)
num=() #空元组
if num:
print(1234)
else:
print(56) #打印56
所谓的循环就是把一件相同的事情重复执行N次,-->比如抄写单词
抄一百遍-->执行100次
在编程中,循环语句的作用是为了让开发:
1.减少代码量
2.提高运行效率
比如说我要输出100次我是最棒的
1.打100次print
2.字符串*100
3.用循环
while循环语句:判断循环条件是否为真,满足就循环执行代码,不满足结束循环
语法格式:
while 循环条件:
执行语句
更新语句
实例:
i=1
while i<=100:
print(f'我在抄书,这是第{i}遍')
i+=1 #等价于i=i+1,也就是说让这个次数每循环一次加一次1
死循环:一直循环,不会停止的
#最简单的死循环:
while 1:
循环语句
while 1: #while True,条件为真,一直满足条件
print(123) #一直打印123
可以理解为while的升级版,作用跟while相似
在1.在遍历数据时2.循环次数已知时,会比while更高效
遍历(迭代):在一堆数据里,把这些数据一个个的取出来
1.可迭代对象:以后在专门讲,现在理解为有多个数据的值
2.里面的变量:这里的变量是作为临时容器用,一般取名i,也可以叫其他的,但是默认这个i这个变量是不需要提前声明,作为一个临时存储的作用
1.遍历数据
语法格式1:
for 变量 in 可迭代对象(字符串,列表,元组,字典,集合)
执行语句
实例:
li=['伊诺',123,True,88.88,'多喝热水']
for i in li:
print(i) #把列表里的数据一个个取出来,赋值给i
2.确定了循环指定的次数
语法格式2:
1.for 变量 in range(数值):
实例:
for i in range(100): #要循环多少次,里面就填几,循环了100次
print(i)
2.for 变量 in range(起点,终点):
实例:
for i in range(3,71): #设置了起点值 3 到终点70
print(i)
2.for 变量 in range(起点,终点,步长):
for i in range(1,100,2):
print(i)
range() 这个方法 可以表示一个数值的范围 结合 in 就可以做一个简单的数值范围判断
range的值默认从0开始,终点值到它的前一位
break-->终止,结束本轮循环
continue-->跳过,跳过本次循环
1.本来要跑100圈,你跑了10圈就偷懒了选择摆烂--break 结束循环
for i in range(1,101):
print(f'我跑了第{i}圈')
if i==10:
print('我不跑了')
break
2.抄书,找到一些页面我就跳过不写,耍滑头-->continue 跳过
for i in range(1,21):
if i==10 or i==15 or i==20:
continue
print(f'这是我抄书的第{i}遍')
if 判断条件:
空着不写
while 判断条件:
空着不写
如果你空着不写,这样会报错,因为你写了一个if或者循环语句,但是里面又不写内容,相当于站着位置不干活,会造成性能浪费
但是在开发的时候,会遇到这种情况
已知一个地方要写一个条件判断/循环,但是还没有想好底下写什么东西,这时就可以先写个pass,表示跳过,防止程序报错
if 判断条件:
pass
while 判断条件:
pass
a=1
if a==1:
pass
print(123)
现在那你是个宫女 有个飞上枝头变凤凰的机会 你现在要在御花园里邂逅这个皇上
你去问皇上身边的太监:'皇上会不会来'(第一个判断)
如果来 我是跳舞还是唱歌(第二个判断) 吸引皇上
如果跳舞就飞黄腾达
如果唱歌就拖出去斩了
如果不来 白日梦破灭
'''
1.皇上会不会来
2.来 我是唱歌/跳舞
3.不来 梦破灭
'''
boy=input('小李子,皇上会不会来')
if boy=='会':
talk=input('那么我是唱歌还是跳舞好呢')
if talk=='跳舞':
print('好美啊,封为贵妃')
elif talk=='唱歌':
print('好难听,斩了')
else:
print('请你正确选择')
elif boy=='不会':
print('白日梦破灭')
else:
print('请你正确回答')
我想做个数字方阵长宽各为5 该怎么输出呢
2 2 2 2 2
2 2 2 2 2
2 2 2 2 2
2 2 2 2 2
2 2 2 2 2
for i in range(5): #range 就是范围 相当于范围到5 #列
for j in range(5): #不能使用两个i,因为分不清,#行
print('2',end=' ') #end 换成空格的字符串就不换行 因为有空字符串替代了print原本的\n属性
print('') #到第五个就换行,因为print自带换行功能
print输出函数,默认是有换行这个属性:里面有一个属性叫做end
end的默认值是\n
end=''的意思是给末尾end传递一个空字符串,你print打印时加了这个end='',就相当于print没有自动换行的这个功能了,因为你是传递了一个空字符串替代了\n
序列类型的概念:数据的集合,在序列类型里面可以存放任意的数据也可以对数据进行更方便的操作 这个操作是叫增删改查(curd)
( 增加(Creat),读取查询(Retrieve),更新(Update),删除(Delete) 几个单词的首字母简写)
增删改查是操作数据最底层的操作(从本质除法 我们对数据所有的行为归根到底就是增删改查四个字)
增加新的数据
修改原有数据
查看指定数据
删除指定数据
因为我们在操作序列类型数据的时候,会经常用到增删改查操作 所以python给我们提供了一些内置的功能函数
作用就是帮助我们更好的对数据进行增删改查
方法都是固定好的语法 不需要死记硬背
如果忘了翻笔记.百度,pycharm还会有代码补全
len函数-->获取一个容器的长度/一个容器里面有几个数据
语法:
len(数据)
案例:
a=[1,2,3]
b='好好学习'
c='陌 上'
print(len(a),len(b),len(c))
food = [‘麻辣烫’,‘螺蛳粉’,‘火锅’,‘泡菜’]
1.append:追加一个数据,添加一个数据到列表的最后一位
列表.append(内容)
food.append('奶茶')
food.append(['蜜雪冰城',12])
2.insert:在指定的位置上添加一个数据,原数据会被挤到后面(插队)
列表.insert(下标,内容)
food.insert(0,'咖啡')
food.insert(3,'幽兰拿铁')
3.extend:追加一个序列类型的数据到最后一位
列表.extend(序列内容)
[1]追加单个字符串,是把字符串拆分追加(不能追加单个数字)
food.extend('冰激凌') #单个字符串是打散
food.extend(11) #报错,不能是单个数字
[2]追加一个序列类型,把值分别追加进去
food.extend((1,2,3)) #添加序列类型的值进去
food.extend(['绿豆雪糕',12])
1.pop:在有指定下标后删除一个值 没有指定的下标时 会默认删除最后一个数据
列表.pop()
food.pop() #默认删最后一位
列表.pop(下标)
food.pop(0) #删除指定下标的数据
2.remove: 删除一个指定的数据 如果有重复的数据 从第一个开始删
列表.remove(数据)
food.remove('螺蛳粉')
3.clear: 清空列表里的所有数据
列表.clear()
food.clear()
4.del 删除数据.也可以直接删除这个变量
1.删除整个变量
del 变量名
2.删除变量里的值
del 列表[下标]
del food[1] #删除food里下标为1 的数据
1.修改单个值:通过索引直接修改
列表[下标]=值
food[0]='水果'
2.修改多个值:通过切片来修改
列表[起点:终点]=数据1,数据2,数据3,...
food[1:4]='草莓','葡萄','芒果','榴莲','香蕉'
print(food)
所有的查询方法,里面的内容是显示出来看的,而不是修改的,所以都要用print来输出
number=[1,2,5,3,4,68,4,2,6,1,1]
1.index: 根据内容,获取指定数据的下标
列表.index(数据) #默认从下标为0的位置开始搜索
print(number.index(68))
列表.index(数据,起点下标) #从起点下标开始找数据
print(number.index(1,4)) #从4这个下标开始找第一个1这个数据的下标
2.count: 求和,统计数据出现的次数
列表.count(数据)
print(number.count(1))
num = [6.66,520,70,123,888,False,9]
sort: 对列表的内容进行排序. 如果列表里面有字符串是不可以排序.
列表.sort() #默认是升序排序 从小到大
num.sort()
print(num)
列表.sort(reverse=True)
num.sort(reverse=True) #从大到小
print(num)
demo=(30,34,24,520,True,520,'好好学习')
1.index:根据内容,获取指定数据的下标
元组.index(数据) #默认从下标为0的数据开始搜索
print(demo.index(520))
元组.index(数据,起点下标) #从起点下标开始找数据
print(demo.index(520,4))
2.count: 求和,统计数据出现的次数
元组.count(数据)
print(demo.count(520))
元组不可修改,所有没有增删改的操作,没有修改的方法
字符串和元组一样是不可变类型,里面的数据是不可以改变的,除非重新赋值,否则里面的数据是改变不了的(所有的字符串的方法操作都要用print来输出才能看到效果)
字符串本体是不变的, 但是可以通过方法给你看修改结果
女孩子都喜欢化妆
人的脸 不管你怎么化妆 人是不会换的 还是原来的你
字符串本体--不变
但是可以给你看改变的样子--化妆的样子
talk = ‘我爱学python,每天都要学习’
字符串严格来讲没有专门的增加方法,直接用+拼接即可
字符串+字符串
print(talk + '所以你今天学了吗') #这样可以看到talk拼接后的效果
print(talk)#字符串本体不变
talk1='你这傻逼玩的这么傻逼的操作还来玩游戏'
replace:可以删除/可以替换
字符串.replace('要删除的值','') #把你要删的值,改为空
print(talk1.replace('傻逼', ''))
字符串.replace('要修改的值','新的值')
print(talk1.replace('傻逼', '**')) #把敏感词用*来替代
字符串.replace('要修改的值','新的值',修改的次数)
print(talk1.replace('傻逼', '**',1)) #把傻逼修改一次
name=' Hello World hello world 陌上 '
upper:字符串里的字母全部大写
字符串.upper()
print(name.upper())
lower:字符串里的字母,全部小写
字符串.lower()
print(name.lower())
title: 字符串里的单词首字母改为大写. 以空格为标准
字符串.title()
print(name.title())
strip: 去除字符串左右两边的空格
字符串.strip()
print(name.strip())
split: 切分.根据指定的内容.切分字符串
字符串.split('分割对象')
print(name.split('o'))
find:通过内容获取数据的下标
字符串名.find(内容)
print(name.find('o'))
字符串名.find(内容,下标)
print(name.find('o',6))
count:求和,统计数据出现的次数
字符串.count('数据')
print(name.count('l'))
isdigit: 判断字符串里是否为纯数字.结果为布尔值
字符串.isdigit()
print(a.isdigit())
print(aa.isdigit())
isalpha: 判断字符串是否为纯中文/字母
字符串.isalpha()
b='yn陌上'
bb='yn陌上12'
bbb='yn陌上%$'
print(b.isalpha())
print(bb.isalpha())
print(bbb.isalpha())
endswith: 判断字符串的后缀.是否为指定字符.结果为布尔
字符串.endswith('数据')
print(c.endswith('很帅'))
print(c.endswith('很棒'))
后面我们可能也会遇到这种场景 把jpg后缀的图片改为png后缀的
可以用到这个方法
主要用来判断后缀
数据类型分为3种
前面已经学过了两种类型:
1.数值类型:int/bool/float 只能存储单个数据
2.序列类型:list/tuple/str,有序的存储多个数据--有序类型,有下标,可以进行切片索引步长的操作
3.散列类型:
1.可以存放多个数据
2.内部是无序的(没有下标)
3.内部数据不重复
集合跟字典都是散列类型
集合(set)
表示形式为:用大括号{}包裹起来的数据,里面的数据用逗号隔开
集合的特性:
1.唯一性
2.无序性 主要是用来进行去重和逻辑判断
语法:
集合名={数据1,数据2,数据3,....}
案例:
room={'许叶彤','李震','尹天浩','帅过过','吊炸天'}
print(type(room))
print(room)
num={1,5,6,7,8,9,1,5,6,2}
print(num) #正常输出一个集合,里面的重复元素会自动去除,代表集合的唯一性
#print(num[2]) #报错,因为集合是无序类型 没有下标
集合可以进行简单的逻辑运算,交并差集
集合1 & 集合2-->获取交集--一个数据,两个集合里都有它
集合1 | 集合2-->获取并集--两个集合里的所有数据(去重)
集合1 - 集合2-->获取差集--两个集合之间,自己独有的数据
符号输入
& --> shift + 7
| --> shift + \
- --> 减号
生活例子:现在我们有两个碗
碗A{花菜,鸡肉,凤爪}
碗B{鸡肉,豆腐,梅菜}
交集-->两个碗里都有的菜-->鸡肉
并集-->两个碗里所有的菜-->花菜,鸡肉,凤爪,豆腐,梅菜
差集-->碗A-碗B-->碗A独有的数据-->花菜,凤爪
碗B-碗A-->碗A独有的数据-->豆腐,梅菜
num1={1,2,3}
num2={3,4,5}
print(num1&num2) #交集{3}
print(num1|num2) #并集{1, 2, 3, 4, 5}
print(num1-num2) #差集{1, 2}
print(num2-num1) #差集{4, 5}
集合里可以放很多数据(不能放列表)
集合里只能放不可变的数据
talk={'你好',66,9.9,True,(1,2,3),[1,2]}
print(talk) #集合里不能放列表,会报错
集合的本质:
1.存储非重复数据-->自动去重
2.进行逻辑判断,进行交并差运算
room= {‘麻子’,‘高启盛’,‘老莫’,‘高启强’}
add: 添加一个数据到集合里
集合.add(数据)
room.add('好好学习') #随机,因为无序所以随机增加
update: 把一个序列类型打散后添加到集合里
集合.update(序列数据)
room.update('别做坏事')
pop: 删除一个数据(随机删除)
集合.pop()
room.pop()
remove: 删除指定的数据
集合.remove(数据)
room.remove('高启强')
clear:清除所有数据
集合.clear()
room.clear() #set()
字典(dict)
表示形式为:字典是用大括号包裹起来的数据,存储数据是以键值对的方式来存储,数据之间也要用逗号隔开,主要存储一些带有'说明'性质的数据
键值对 左边是键 中间冒号 右边是值
key:value-->相当于键是名字,值就是数据
键名一般是用字符串或整型来表示
值里面什么都可以放,放变量,函数,杂七杂八的都OK
声明语法:
字典名={键:值,键:值}
info={'姓名':'陌上','余额':8.8,'年龄':18}
info1={
'姓名':'陌上',
'余额':8.8,
'年龄':18
}
字典的输出:
print(字典名)
print(info)
print(type(info))
print(字典名[键名]) #输出指定键的值
print(info['姓名']) #陌上
#姓名=伊诺,年龄=18,余额=8.8
这里的字典的作用是一个说明效果,方便理解,有一个较好的可读性
用字典类型保存的数据有一点好处:
比起用列表/元组存储数据,他看起来更加清晰
info={'陌上',8.8,18} #这里的一些数据如果不加注释说明,可能不清楚表示什么东西
所以如果要的数据,有明显的对照关系,就可以用字典来保存,看起来更加的清晰明了
字典的特性:
1.字典是通过键值对的方式来获取数据,而不是通过下标索引获取
2.字典里的键是不可变的,只能使用数字,字符串,或者元组,不能使用列表
day=(2,3)
food={
1:'肉',
'水果':'葡萄',
day:'打折'
}
print(food)
info2={
[1,2]:'陌上'
} #报错
#print(info2) #报错,字典里的键是不可变的,只能使用数字,字符串,或者元组,不能使用列表
3.字典里的键值是可以修改的,还可以嵌套(字典里面还可以放字典)
info3={
'姓名':'陌上',
'余额':[8.8,9.9,10],
'地址':{1:'工作地址',2:'家乡地址'}
}
print(info3)
4.字典里键名是唯一的
info4={
'姓名':'伊诺',
'余额':8.8,
'年龄':18,
'年龄':19,
'年龄':20
} #只会保留最后一个年龄的键值对
print(info4)
总结:用一个看起来更清晰的方式来保存数据,保存方式为键值对
可以把键值对理解为变量 键就是变量名 值就是变量值
info={
'姓名':'陌上',
'余额':8.8,
'年龄':18
}
setdefault: 给字典添加一个键值对. 如果已经有这个键了.就不会新增
[1.新增一个键,没有写值,值默认为空]
字典.setdefault(键名)
info.setdefault('身高') #没有值,值默认为空
[2.新增一个键值对]
字典.setdefault(键名,值)
info.setdefault('家乡','陕西宝鸡')
pop: 通过键名删除指定的数据
字典.pop(键名)
info.pop('年龄')
popitem: 删除一个键值对,从最后一个数据开始删
字典.popitem()
info.popitem()
clear: 清除整个字典
字典.clear()
info.clear()
update: 以键值对的方式修改数据.如果没有就新增
[1.修改数据]
字典.update({键:想修改的值})
info.update({'姓名':'陌上帅哥'})
[2.如果没有这个键值对,就转为新增]
字典.update({键:值})
info.update({'毕业学校':'西安邮电大学'})
[3.增加多个键值对]
字典.update({键:值,键:值})
info.update({'职业':'学生','性别':'女'})
字典[键名]=值 #修改指定键的值,键是存在的情况下会讲原来的值进行修改,否则添加为新的键值对
info['性别']='男' #找到info里面的性别 把值改为男
info['生肖']='猴' # 也算是一个新增方法,创建新的键值对
字典跟集合一样是无序序列,所以是无法通过下标进行获取数据,但是字典有查询数据的方法,但是查询的方法依旧也是用print来输出
get: 通过键名,获取值. 如果没有这个键,输出None
字典.get(键名)
print(info.get('余额'))
print(info.get('籍贯')) #没有籍贯这个键,就输出None
keys: 获取所有的键
字典.keys()
print(info.keys())
values: 获取所有的值
字典.values()
print(info.values())
items: 获取所有的键值对
字典.items()
print(info.items())
列表名=[] #声明一个空列表
元组名=() #声明一个空元组
字符串名='' #声明一个空字符串
集合名=set() #声明一个空集合
字典名={} #声明一个空字典
如果你要出国玩,翻译工具-->把你想说的话,通过翻译工具的方式,传达给别人
计算机语言最底层是由0和1组成,计算机是怎么做到吧一堆的0和1变成我们看到的字,--->字符编码-->在计算机里面有一个翻译工具,作用就是把机器码数据转换成人类看的懂的字
字符编码--翻译工具--把计算机的东西翻译成人类能理解的东西
第一套字符编码叫ASCII码,里面收纳了一些常用符号,数字,字母-->没有中文或者其他语言
asciima表用法就有点类似于字典-->每个字在表里都有对应的一个序号,可以通过序号找到字,也可以通过字找到序号
但是随着科技进步发展,很多国家都有了自己的计算机技术能力,这时候这个ascii码表就不能满足需求了,-->我要用中文.日文
后面很多国家,地区都研发了一套自己的字符编码:
中国研发GBK编码-->有两万多个汉字
同时间中国台湾-->big5码,大五码,繁体字
每个国家的语言 不同 所以只显示自己国家的文字
用别的国家软件就容易出现问题
#就比如说用GBK写的内容用big5码打开就可能是乱码不通用
针对这个问题,有个国际组织,专门收集了全世界大部分的国家的语言文字,汇总做了一个大字典并推行使用,以后统一用大字典就可以尽量避免乱码问题-->utf-8
核心点:
1.目前世界上最主流的编码是utf-8,#大部分默认就用utf-8
2.一个程序是用什么编码写的,就用什么编码去打开
在程序中每个字都是有对应的序号
ord(字符) -->通过字符,找到序号
chr(序号) -->通过序号,找到字符
print(ord('A'))
print(ord('B'))
print(chr(65))
print('A'>'B') #实际比较的是ascii表的序号
凯撒密码 凯撒加密
计算机自动关机的指令 先按win+r 或者打开cmd
指令:shutdown -s -t 秒数
shutdown -a 取消关机
import os # 准备一个作案工具.这个工具可以让你运行cmd指令
code = "rgtscnvm,r,s2222" # 被加密过后的数据 #shutdown -s -t 秒数
run = "" # 空的字符串
for i in code: # 写了一个循环,把这个字符串里的所有元素都取了出来
run+= chr(ord(i)+1) # 把每个元素都+1,并添加到run里面
os.system(run)
编程函数!=数学函数,里面的是逻辑,功能,而不是套公式
编程函数的作用是实现特定操作的一段代码
生活例子
我现在请客,每个人,我都点了一份一样的吃的
1.上校鸡块
2.可乐
3.薯条
100个同学 都点这样的 炸鸡店的老板我需要
这个点餐比较麻烦,我要重复说一百次
这个时候会用到-->套餐
出个套餐,美味套餐(上校鸡块,可乐,薯条)
我现在要点单 我只需要干嘛 美味套餐来一百份
程序:
把一些会经常用到代码保存起来,取个有意义的名字,以后要用直接调用就OK
变量:保存一个/多个数据
函数:保存的是一段或者多段代码
其实函数我们也并不陌生
print (输出函数) input(输入函数) 内置函数
函数的优点:
1.遇到重复代码时,可以定义为函数,省事
2.修改起来比较方便
本质:写好的一些代码,可以实现特定的功能,取个好记的名字保存起来方便使用
函数的命名规则和变量是一样的:
1.由数字,字母,下划线组成
2.不能数字开头,不能有其他特殊符号
3.区分大小写 fun Fun
4.不能用关键字/内置函数 print input type
5.见名知意
函数如果没有特别作用,没想好别的名字 可以取名fun
函数的使用分为两步
#先定义再调用,程序是从上往下执行
1.声明-->define-->def
2.使用,调用函数
1.定义函数
def 函数名():
代码内容
def fun():
print('好好学习')
调用函数:在函数名后面加个括号,就是调用函数
函数名()
fun()
实例:
#定义函数
def fun():
print('好好学习')
#调用函数
fun()
2.声明空函数,还没有想好内容,为了防止报错,就先写个pass
def 函数名():
pass
def fun_2():
pass
函数里的数据如果是一成不变的,那很鸡肋,函数会接触到各种各样的数据,函数可以根据情况,来接收一些数据,并在函数里处理
让函数里的内容可以更加灵活,数据不是定死的-->函数参数
形参-->没有具体数据,只是先占个位置-->定义阶段
实参-->有具体的数据,在运行时取代形参-->调用阶段
声明带参函数:
def 函数名(形参):
代码
def fun(money):
print(f'我最喜欢{money}了')
调用带参函数
函数名(实参)
fun(50)
fun(100)
fun(1000000)
一个萝卜一个坑,不要多,也不要少,你定义了几个形参,就传几个实参,否则就会报错
有几个形参,就传几个实参,数量要一致
定义时:
def 函数名(形参1,形参2,..):
代码
调用时:
函数名(实参1,实参2,...)
例:
def add(num1,num2):
print(num1+num2)
add(70,520) #少写多写都会报错
在声明参数的时候就提前赋好值,作为一个默认的参数
定义时:
def 函数名(形参1,形参2=值):
代码
调用时:
函数名(实参1)
例:
def fun(money,people='陌上'):
print(f'{people}最喜欢{money}了')
fun(100)
fun(50)
fun(50,'许总') #不会报错,但是学_恒会覆盖原来的陌上
注意:赋值的默认参数要放右边,不能放左边
有的时候可能出现,不清楚这个函数会接收多少个参数,这时候就用不定长参数
不定长参数可以一次性接收多个数据, 接收到的数据为元组类型
不定长参数的表现形式:*
参数名是不固定,但是正常规范命名都是取名为*args
定义时:
def 函数名(*args):
代码
调用时:
函数名(值1,值2,值3)
例:
def room(*args):
print(args)
print(args[1])
room('李白','王维','杜甫','杜牧','老子','孔子')
#想好了具体传什么形参的时候,剩下的还没有想好,也可以结合不定长参数1使用
def message(name,age,*args):
print('''
-----个人信息表-----
姓名{}
年龄{}
'''.format(name,age))
print(args) #('李白', 25, 8.8, (0, 1))
print(args[0]) #李白
print(args[1:]) #(25, 8.8, (0, 1))
print(args[1::2]) #(25, (0, 1))
message('陌上',18,'李白',25,8.8,(0,1))
可以一次性接收多个数据,接收的数据类型为键值对,得到的数据为字典类型
不定长参数2的表示形式为:**
参数名同样不固定,但最好叫**kwargs
定义时:
def 函数名(**kwargs):
代码
调用时:
函数名(键=值,键=值) #键不用加引号
实例:
def fun_2(**kwargs):
print(kwargs)
fun_2(name='陌上',age=18)
def grade(C,M,**kwargs):
print(f'Chinese{C},Math{M}')
print(kwargs)
grade(98,99,java=100,python=500)
def fun_3(a,b,*args,**kwargs):
print(a*b)
print(args)
print(kwargs)
fun_3(5,10,java=100) #a对应了5,b对应了10,java=100对应了**kwargs,*args没有传值,所以是一个空元组
fun_3(5,10,5,6,7,8,9,java=100)
注意:不定长参数1必须要在不定长参数2前面
def add(num1,num2):
print(num1+num2)
add(520,70)
a=add(520,70)
# b=a+1 #报错 不支持无类型跟整型相加
# print(b)
print(a)
如果没有定义返回值 会返回一个None空
在函数里,一个数据只是用print输出.那就只能看,不能用,如果你想要用这个数据,需要的是return来返回,而不是print输出
return 返回值
把值返回给函数本身,可以用来使用 返回值一般是结合函数参数来使用
那现在我们要用一个有返回值的函数怎么做?
1.定义一个带有return返回值的函数
def 函数名():
return 数据
2.输出返回值内容:把函数名()用print包裹起来,这个动作就会达到目的是:
1.运行函数,2.输出函数的返回值
print(函数名())
实例:
def fun(a,b):
return a+b
fun(3,5) #直接调用函数 不会显示出返回值的内容
print(fun(3, 5)) #所以要打印返回值需要print
返回值可以有多个,并且也可以输出多个返回值,得到的类型是元组类型
def 函数名():
return 返回值1,返回值2,...
def fun3():
return '么么哒',1,True,[1,2,3]
print(fun3())
得到的返回值还有一种用法是可以把函数返回值赋值给变量
变量名=函数名() #把函数返回值赋值给变量
例:
def fun(a,b):
return a+b
fun(3,5) #直接调用函数 不会显示出返回值的内容
print(fun(3, 5))
a=fun(3,5)
c=a+10
print(c)
注意:
在return后面的代码是不会执行的,因为函数执行到return就会结束
def talk():
print('大家留下加班')
print('没有加班费')
return 'ok'
print('加你个大头鬼')
talk() #直接调用函数不会显示出返回值的内容
print(talk()) #输出返回值内容
print(talk) #内存地址
返回值细节:
1.返回值的类型是不限的,int/str/folat/list/dict都可以,也可以返回一个函数
2.返回值的数量数不限的,可以返回多个数据,得到的数据是元组类型
python自带的一些功能函数
序列类型/散列类型方法
数据类型转换 int() str() list()
特点:
1.都有一个小括号
2.每个函数都有自己的功能
print():输出函数
input():输入函数
type() : 获取数据类型函数
len(): 获取数据长度函数(里面有多少个元素)
min(): 获取最小值函数
max(): 获取最大值函数
sum(): 获取数据的和 函数
li = [1, 2, 3, 4, 5, 6, 8, 9]
print(max(li)) #最大值
print(min(li)) #最小值
print(sum(li))#和
print(len(li)) #长度
函数命名不要取名为内置函数的名字!!!
基于函数的注释,看起来和注释差不多,但是可以被调用,在学函数是,更推荐使用文档字符串,里面可以写
1.这个函数是干嘛用的
2.这个函数参数是干嘛用的
3.返回值是干嘛用的
def add(a,b):
'''
我是一个加法函数
:param a:int型
:param b:float型
:return:a+b
'''
return a+b
print(add(2,2.3))
print(add.__doc__)
print(print.__doc__)
输出方式:注意是两个下划线
函数名.__doc__
print(print.__doc__)
print(input.__doc__)
print(max.__doc__)
流程控制语句
三大执行方式:
1.顺序执行:程序从上往下依次执行
2.选择执行:根据条件满足与否,执行对应的代码
3.循环执行:根据条件满足与否,循环执行对应的代码
if 选择执行/分支语句
分支语句分为三种
1.单分支--if--如果满足if条件就执行对应代码
if 判断条件:
执行语句
2.双分支--if,else--如果满足if条件就执行if里的代码,否则执行else里的代码
if 判断条件:
执行语句
else:
执行语句
3.多分支--if,elif,else--如果满足if条件就执行if里的代码,不满足就接着判断是够满足elif的代码,满足就执行elif的代码,elif也不满足才执行else的代码
if 判断条件:
执行语句
elif 判断条件:
执行语句
else:
执行语句
一组分支里面,if和else只能有一个,elif可以有多个
if还有个特性 判断条件有值就执行 没值的情况就不执行
有值为真 没有值为假(0,None,'',[],{},set())
流程控制语句中代码块的概念,通过tab缩进来控制,一般一个tab是4个空格
循环语句:
判断条件是否满足,如果满足条件就循环执行,不满足是结束循环
死循环--一直执行,不会结束的循环
while 循环:
语法:
while 循环条件:
执行语句
更新语句 #如果你条件不更新,那就会一直死循环
num=1
while num<=100:
print(666)
num+=1
for 循环:在(1)循环已知次数 (2)遍历数据 都比while更高效
语法:
for 变量 in 可迭代对象: #可迭代对象理解为有多个数据的值即可,这里的变量取名为i
执行语句
talk='伊诺老师提前祝大家端午安康'
for i in talk:
print(i)
for i in range(10) #循环10次,i的值为0-9
for i in range(1,11) #循环10次,i的值为1-10
for i in range(1,11,2) #循环5次,i的值为1,3,5,7,9 步长为2
range的起点默认为0.终点到他的前一位
break--直接结束本轮循环
continue--跳过本次训话
break 和continue 一般结合循环里的if来使用 如果满足条件就break
pass --没有写好内容 为了防止报错 可以先写个这个
序列类型方法:
方法有很多,不需要死记硬背,要用的时候根据需求来查
1.列表的方法中,增删改直接写,不需要print,查需要print
2.元组只有查询方法,因为元组不支持修改,所以元组的内容要结合print来输出
3.字符串的数据是不可变的,所以字符串也要结合print来输出
用的比较多的方法:
append--列表追加数据
insert--列表插入数据
index--查询数据下标
replace--字符串修改数据
散列类型(set集合,dict字典):
1.可以存储多个数据
2.里面的数据没有顺序概念(没有下标)
3.数据不能重复
set-->集合,表示形式为用大括号包裹起来的数据,里面的数据用逗号隔开,集合里不会存储重复数据
set1 = {1,1,2,3,5,0,4,7,98,7,7,52,0} #重复数据不会真的存进去
集合可以用来进行简单的逻辑运算
&交集(两个集合里共用的元素)
|并集(两个集合所有元素)
-差集(两个集合间,独有的元素)
集合主要用来:
1.数据去重
2.进行简单的交并差判断
dict-->字典,示形式为用大括号包裹起来的数据,里面的数据以键值对的方式来存储,里面的数据用逗号隔开
键值对语法: 键:值 变量名:变量值
info={
'姓名':'陌上',
'年龄':18,
'美女':True
}
用键值对保存的数据,看起来更加清晰明了,所以如果要 保存的数据有明显对应关系,就可以用字典来存储数据
键是唯一的,值可以是任意类型(数值,序列,散列,函数)
字典的输出方式通过键名输出
字典名[键名]
print(info['姓名'])
字典名[键名]=值 #修改这个键的值
info['美女']='丑女'
函数(function):
函数的概念就是把一些经常用到的 代码保存起来,取个名字,以后要用功能,直接调用即可
类似于生活中套餐
函数的使用分为两步:1定义(define) 2.调用
定义函数:
<1>定义一个普通函数
def 函数名():
代码
def fun():
print('好好学习')
<2>定义一个空函数
def 函数名():
pass
def fun2():
pass
<3>定义一个带有返回值的函数
def 函数名():
return 返回值
def fun3():
return 123
<4>定义一个带参函数
def 函数名(参数):
代码
def fun4(name):
print(f'{name}好好学习')
调用函数:
1.直接调用函数
函数名()
fun() #执行fun里的代码
2.输出返回值/函数内存地址
print(函数名) #输出函数内存地址
print(fun3)
print(函数名())
print(fun3())
3.调用带参函数:
fun4('陌上')
函数参数:
形参:没有具体的值,只是先占个位置--定义时
实参:有具体的值,在调用时取代形参运行--调用时
<1>必备参数-- 形参,实参数量要一致,一个萝卜一个坑
def fun(a,b):
print(a,b)
fun(1,2,)
<2>默认参数-- 在定义形参时,就给里面的某个变量赋值,就可以不用传参,赋值只能给右边的数据赋值
def fun_2(age,name='陌上'):
print(age,name)
fun_2(18)
fun_2(18,'帅哥') #帅哥覆盖原来的默认参数值陌上
<3>不定长参数1-- 在不清楚要接收几个数据的情况下可以用它,一次性接收多个数据数据,接收的数据类型是元组类型数据,表现形式为 *参数名 一般取名为*args
def fun_3(*args):
print(args)
print(type(args))
fun_3(66,888,True,'陌上')
<4>不定长参数2-- 在不清楚要接收几个数据的情况下可以用它, 一次性接收多个数据数据 ,可以接收键值对数据,接收的数据类型是字典类型数据,表现形式为 **参数名,一般取名为 **kwargs
def fun_4(**kwargs):
print(kwargs)
print(type(kwargs))
fun_4(python=90,math=80,age=18,name='陌上') #键不用打引号
return返回值:
一个数据如果使用print,那就是只是作为输出,是只能看,不能用
所以一个数据想被继续使用,就是通过return的方式,把他返回出去
返回值的默认值为None 为空
return后面的代码是不会再运行
返回值的数量/类型是不限的
文档字符串:
写在函数里的注释,可以被调用,里面写的是函数的相关说明.参数/返回值/这个函数的说明
def 函数名():
"""文档字符串的内容"""
可以通过函数名.__doc__的方式输出 文档字符串的内容
print(print.__doc__)
为什么要分开写 我把加减乘除写到一个函数里不可以吗???--避免一个错,全部错
我把加减乘除函数都写在了一个函数里面,然后里面的除法功能出错了,我这个函数还能用吗?--不能使用
把加减乘除函数分开写在4个函数里,然后里面的除法功能出错了,我这个函数还能用吗?可以先把他屏蔽 注释 也不会影响其他功能
专注做好一件事 彼此联系不要过于紧密
高内聚-->一个程序里/函数里做的事情尽量统一/专一,一个函数做好一个功能就可以了,而不是一个函数里写一堆的功能 容易一个错 整个错
低耦合-->程序与程序之间,函数与函数之间的关联不要过于紧密 各做隔得 ,避免一个错 全部错
函数非常重要,但是不要过于害怕,搞清楚本质
函数 :更高级的容器,里面存的不是数据,而是代码
一个容器能干嘛,函数也可以干嘛
函数对象--把函数当成一个普通的数据容器来使用
def fun1():
return 'hello'
b=fun1() #把函数fun1的返回值 赋值 给了变量b
print(b)
a=print #把函数复制给了一份a 让a了这个print函数的功能
a('你们猜一下我现在a可不可以打印') #举的例子 你们呢 不要就是随意把内置函数去赋值给另外变量
def fun2():
print('今晚大家要表现好哦')
c=fun2 #这个c是函数类型,把函数fun2复制了一份给了c c等价于函数fun2
c() #调用函数
print(c()) #返回值没有定义 是为None
#一般不会把函数存到集合里面 因为存到集合里没有很好的办法给他拿出来值 所以没有意义
def fun():
print('端午安康')
li=['陌上',123,6.6,fun] #这里是把函数放到了一个列表变量里,现在是放这,还没有使用,如果说fun()就直接获取了结果
print(li[3]) #print(fun) 内存地址
# print(li[3]()) # 没有返回值 所有才会输出None
li[3]() #直接调用 不会输出返回值
def fun3(a,b):
return a+b
li1=(66,888,99,fun3,77)
print(li1[3](5.6, 7))
print(li1[3]('端午','安康'))
def name():
my_name='陌上'
return my_name
def name1(a):
print(f'{a}祝大家端午安康')
def name2(b):
print(f'{b}祝大家多吃粽子')
name1(name()) #把name返回值传给了name1 name的返回值就是陌上 所以再作为了参数传给了a
name2(name())
'''
卑微陌上在线学习
老板(任务1,任务2)
陌上(要求1,要求2)
干活
干活
返回 做好的东西
返回 陌上(要求)
'''
#现在员工的返回值就是做好的东西 老板只需要返回我员工函数的返回值就OK了
#最后老板拿着我的东西去邀功
def boss(a,b): #老板收到两个任务(参数)
def yi_nuo(c,d): #我接收到老板的任务,加了两个创意所以是cd(参数)
return c+d #做好东西 返回出去
return yi_nuo(a,b) #老板拿做好的东西 邀功
print(boss(66,88)) #成果是老板的 给老板打工
名称空间:用来存名字的地方
变量名,函数名,模块名
程序中有一些专门的内存区域来保存对应的数据:
名称空间--存储变量名,函数名,模块名
内存数据-->变量值,函数代码,模块代码
生命周期:一个数据./程序 从创建到结束的过程
名称空间 分为三层:
1.内建名称空间(存内置函数)
生命周期:随着python程序启动而生成,在程序关闭时回收.清除所有数据
加载顺序:最先被加载出来的
存放对象:print input type sum 这些内置函数
2.全局名称空间(用户定义在python外层的名字)
生命周期:随着python程序启动而生成,在程序关闭时回收.清除所有数据
加载顺序:第二个加载的
存放对象:用户自己定义的变量名/函数名
3.局部名称空间(在函数里定义的名字)
生命周期:随着函数调用而生成,结束调用后关闭
加载顺序:在调用时才会被加载
存放对象:在函数里定义的变量名/函数名/形参名
三国版:
曹操
内建名称空间:曹操的兄弟,家人,一开始打天下的时候就带着的-->曹仁,夏侯惇,夏侯渊,曹洪
全局名称空间:曹老板打天下过程中收复的文臣武将-->张辽,典韦,郭嘉
局部名称空间:曹老板分封的太守,太守底下的小弟-->太守的小弟听太守的话,但是不一定曹老板的话
a=666 #a定义在外层,属于全局名称空间
def fun():
z=888 #z定义在函数里,属于局部名称空间
print(77)
print(z) #在这里打印 小弟听太守的
fun()
# print(z) #报错 相当于太守的小弟会听太守的话,但是不一定听你曹老板的话
总结:
一个程序里的数据都是会存储在对应的位置
名称空间-->用来存储名字的地方!!!
作用域:一个数据能够使用的范围
wifi:一个网络能够被使用的范围
作用域分为:
1.全局作用域:整个程序里都可以使用
(内建名称空间,全局名称空间)
2.局部作用域:只有局部位置才能使用(函数内)
(局部名称空间)
相当于设了密码的wifi,只有知道密码的人才能使用
#全局变量
b=10 #b 是一个全局变量,整个程序里都可以使用
print(b) #不管是在外层 可以直接输出
def fun2():
print(b)#还是在内层 也可以直接输出
fun2()
#局部变量
def fun3():
c=666 #c是局部变量,正常来说只有函数fun3才可以使用它
print(c)
fun3()
# print(c) #单独在外面打印就会报错
提权操作-->让一个数据,从局部变为全局
global-->全局
def 函数名():
global 变量名
变量名=值
函数名()
def name():
global a #这个语句必须写在你要提权的变量名上面 不能放在下面
a='陌上'
name() #局部名称空间创建 还需要调用函数 才能生成对应的名称空间
print(a)
这样变量名就提权为全局变量 在外层也可以直接调用,记得要调用函数才能生成函数数据!!!
降权操作 --把一个数据,变为私有,本来一个内部的东西大家都能用,现在只有我能用 将局部变量再度局部化
nonlocal-->私有化
def fun():
a=520 #这里的a 从函数角度来说 是全局变量 但是从整个程序来说 他是一个局部变量
def fun2():
nonlocal a #私有化 把本来fun大家的东西 变成fun2的东西 归自己所有 局部变量再度局部化
a=666
fun2()
print(a)
fun()
#fun公司
#fun2部门 部门属于公司的一份子 公司的wifi 对于公司的人来说 wifi就是全局的变量
# 所以也可以用a
nonlocal 比较霸道 把公司内部的wifi抢过来了 相当于把密码改了 只有fun2才能用
我们平时函数都是称为:有名函数
匿名函数顾名思义:无名函数
http://c.biancheng.net/view/2262.html
给懒人用的 -->如果你要写一个函数,但是不想给他取名字,那么就可以用匿名函数来写
定义一个函数 但是没有名字
先写好他的功能 要用的时候再取名字
#有名函数的写法
def add_1(a,b):
return a+b
#匿名函数
add_2=lambda c,d:c+d
print(add_2(90,100))
语法格式:
lambda 变量:操作
lambda a:print(a)
talk=lambda a:print(a)
talk('哈哈')
函数对象-->把函数当成一个普通数据来使用,该干嘛干嘛
1.函数可以用来赋值
2.函数可以放到容器里面(列表,字典,元组)
3.函数可以作为参数传入到另外一个函数
4.函数可以作为返回值
名称空间-->存放python程序里名字的地方
1.内建名称空间--内置函数
2.全局名称空间--定义在程序外部的名字
3.局部名称空间--定义在函数内的名字
作用域:一个数据能够被使用的范围
全局:整个程序里都可以使用
局部:程序里的部分位置才能使用
提权--局部升为全局--global
降权--函数内全局降为局部--nonlocal
匿名函数:
不想给函数取名字是,就可以用它,先把函数功能写好,后续需要使用的时候再取名字
生活中:
有台电脑 它的硬盘空间不够了 里面的资料,重要的文件不能删.不能移动,咋办
1.加装硬盘 -- 直接解决 -->前提是我得电脑 能加装
2.插个u盘 -- 间接解决 --> 没有特别的条件要求,比较灵活
开发潜规则:
代码拓展-->开放-->可以加功能
源码修改-->封闭-->不能修改源码
一个程序做好之后,一般是不会随意删改里面的函数代码的
如果你改了源码,导致程序出bug了,修复起来会很麻烦, 所以一般不会再改源码
还有就是随便就能修改,那这样的代码安全性很差
所以有一个要求 对于一些写好了的代码 不应该再去随意修改它
那如果我要给这个函数加功能,我们的做法是:
不能修改函数的源代码,能够通过间接的方式去修改
直接修改 -- 整容 --修改源代码
间接修改 -- 化妆 -- 通过装饰器
闭:封闭,指的就是一个嵌套函数里的内层函数
包:用内层函数,来操作外层函数得到的数据
作用:间接修改数据 保护私有数据不被轻易修改
闭包函数必备的条件:
1.必须是一个嵌套函数
2.内层函数必须操作外层函数数据(这个数据可以是一个变量或者函数参数)
3.外层函数必须返回内层函数
闭包可以说就是为了装饰器而生的,单独写闭包函数意义不大,一般都是配合装饰器来使用
闭包格式:
def 外函数名():
def 内函数名():
代码
return 内函数名 #返回内存函数就行 不需要调用函数
#如果没有封闭的函数 会不会被轻易修改数据呢?
#有个打工仔 陌上
#钱包
money=0
#定义工作的函数
def work():
global money
money+=100
work() #工作一天
print(money)
work() #工作2天
print(money)
work() #工作3天
print(money)
#天有不测风云 钱被抢了
money=0
print(money)
#重新工作
work()
print(money)
#上面的这个情况因为没有封闭很容易被修改(被抢)
#闭包
def person():
money=0
def work_1():
nonlocal money
money+=150
print(money)
return work_1 #返回内存函数就行 不需要调用函数
res=person() #res 等同于 work_1
res() #res() 等同于 work_1()
res()
money=0
res() #450 并没有修改 因为我们这里是封闭的,闭包就是保护私有数据不被轻易修改
#不是闭包
def person_1():
def work_2():
money = 0
money+=150
print(money)
return work_2 #返回内存函数就行 不需要调用函数
f=person_1()
#检测闭包函数的使用:函数名.__closure__
print(res.__closure__) #cell 闭包的意思
print(f.__closure__) #None 不是闭包 因为他不满足闭包的条件之一是因为内层函数没有操作外层函数的变量或者参数
#闭包 操作外层函数的参数
#加料是一个可以给<函数>加功能的函数
#肠粉 是形参 只是一个名字 会接收一个函数 是给你要加功能的函数先占个位置
#加料是一个工具 作用就是一个函数,给这个函数加一句话(加蛋功能)
def 加料(肠粉):
def 加蛋():
肠粉() #肠粉本质是一个函数 函数可以作为参数传入函数 就是让传进来的函数 先调用 确保他原来的功能可以用
print('我加了个蛋')
return 加蛋
def 瘦肉肠():
print('我是一条瘦肉肠')
def 原味肠():
print('我是一条原味肠')
瘦肉肠=加料(瘦肉肠) # 把瘦肉肠传进去,让他加料 最后得到的就是加好料之后的 蛋肉肠
瘦肉肠()
原味肠=加料(原味肠)
原味肠()
def process(a): #准备加功能的东西 a只是一个形参 给要加功能的函数占位置
def product():
a() #把你要加功能的东西拿过来(这里实际调用的是要加功能的函数)
print('我要加个鸡爪')
return product #把加好功能的函数 再返回出去
def food():
print('我是螺蛳粉')
def fruit():
print('我是水果')
food=process(food) #函数加好功能之后 重新又赋值给了原函数
food()
fruit=process(fruit)
fruit()
装饰器:本质就是一个函数,是一个特殊的闭包
添加装饰器的前提
1.要有闭包函数的存在
2.要有被装饰的函数
装饰器的作用就是在不修改函数源代码/参数的前提下,给函数添加功能,并且可以给多个函数添加功能
优点:
1.通过间接的方式,保护私有数据不被轻易改变,给函数加功能,更安全
2.可以给多个函数增加功能,更方便
拿淘宝举例子
私聊客服/购买/收藏-->功能函数
我要加一个功能,判断是否登录,如果登录了才能正常使用,否则跳转到登录界面
def 私聊客服():
判断是否登录
def 购买():
判断是否登录
def 收藏():
判断是否登录
我现在只是两三个函数 那如果我有几十个函数都要在函数里面写重复判断登录的逻辑 很笨 也不方便 很麻烦
我专门写个工具函数,作用就是给函数增加一个功能,-->判断是否登录装饰器--给一个函数添加功能/反复使用-->写好一个判断是否登录的装饰器,然后把这个装饰器加在其他函数里就可以了
上面的加料肠粉函数,就属于一个装饰器函数:
1.加料只是一个工具函数,作用是给一个函数添加功能
2.要给函数加功能,就得接受函数 肠粉就是 函数的形参
3.接收好函数之后,先用传进来的函数,确保原来的功能可以正常使用
4.调用函数后,在内层函数里添加对应的功能
5.返回内层函数(原函数+添加了的功能)
装饰器的使用方式:
1. 函数名=装饰器(函数名) #用加了功能的函数重新赋值
原味肠=加料(原味肠)
原味肠()
2.语法糖
@装饰器名 #快速给下面的函数添加装饰器的功能
def 函数名():
代码
调用函数
@加料
def 玉米肠():
print('我是一条玉米肠')
def 加料(肠粉):
def 加蛋():
肠粉() #肠粉本质是一个函数 函数可以作为参数传入函数 就是让传进来的函数 先调用 确保他原来的功能可以用
print('我加了个蛋')
return 加蛋
#语法2:
@加料
def 玉米肠():
print('我是一条玉米肠')
玉米肠()
@加料
def 蘑菇肠():
print('我是一条蘑菇肠')
蘑菇肠()
def girl(person):
def make_up():
person() #使用外层函数的参数
print('给他画一个美美的妆')
return make_up
@girl
def role_1():
print('我是男一号许叶彤')
role_1()
@girl
def role_2():
print('我是男二号牛牛')
role_2()
#如果你的相亲对象 离异带俩娃 如果你们成了 是不是还要给俩孩子准备房间
#带参装饰器也一样 所以也要 给后面要加功能的函数 先预留位置
#错误用法
def girl(person):
def make_up():
person() #使用外层函数的参数
print('给他画一个美美的妆')
return make_up
@girl
def role_1(friend):
print('我是男一号许叶彤'+friend)
# role_1('宝贝') #报错 因为 你这里带了参数 make_up没有给你准备位置
#相当于make_up 只准备男一号许叶彤 他不知道你带了朋友
#也就是说如果你要加功能的函数 是有参数的 是不是也要参数一起接收过来?
#没接收的话函数就不完整了 程序就不给你面子报错
#正确的做法
def girl_2(person):
def make_up_2(*args,**kwargs):
person(*args,**kwargs) #使用外层函数的参数
print('给他画一个美美的妆')
return make_up_2
@girl_2
def role_2(friend1,friend2,friend3):
print(f'我是男一号许叶彤,我带了朋友{friend1}和{friend2}以及{friend3}')
role_2('李白','王博','轩昂')
#有参无参都可以加*args,**kwargs!!!
def girl(a):
def make_up(*args,**kwargs):
a(*args,**kwargs)
print(1111111)
return make_up
@girl
def role_1():
print(22222)
role_1()
什么情况下会用到装饰器:
一个相同的功能会在很多函数都会用上(登录,验证码)这种情况就可以把函数写为装饰器
特性:
在不修改源代码/调用方式的基础上,给函数添加功能
实现原理:
1.在一个嵌套函数中,用外层函数接收一个函数作为参数,内存函数就会接收函数的参数
2.在内层函数中调用函数,并写上要增加的功能
3.外层函数.返回内层函数-->返回出去的就是(要添加的功能的函数+添加的功能)
以后我们一般不怎么用print-->以后做网站后台/小程序后台/爬虫
1.爬虫的东西一般就是发送请求.保存数据
2,.写后台的都是操作数据,-->输出内容是前端干的
有一个项目有几百行代码,运行没有报错,但是有的功能没有实现,这时候就可以用print实现调试
比如代码一共500行,现在报错了
这个时候可以在100.200,300,400各写一个print .运行程序,看看程序运行到哪个print 那个print没有输出 就知道是哪一段有问题
输出了200,前200行代码没问题,后面的代码有毛病
https://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html
https://www.cnblogs.com/Jerry-Chou/archive/2012/05/23/python-decorator-explain.html
https://www.cnblogs.com/cotyb/p/5243252.html
https://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html
闭包:在一个嵌套函数中,用内层函数修改/操作外层函数的数据
装饰器:给一个函数间接的,不修改源代码的前提下增加功能
装饰器:
1.接受的参数是一个函数--要加功能的函数
2.返回出去的也是一个函数-->装饰器的内层函数
3.装饰器的内层函数做了什么:1.调用传进来的函数,确保原来的功能可以使用 2.添加新的功能 此时内层函数==原函数+功能
4.用此时的内层函数给原函数赋值,就是做到了没有修改源代码,并添加了功能
def talk(a):
def talk1(*args,**kwargs):
a(*args,**kwargs)
print('我是学生')
print('我已经学这么多了了,我觉得我很棒')
return talk1
@talk
def fun():
print('我是相公')
fun()
@talk
def fun1(age):
print(f'我是陌上,我今年{age}岁了')
fun1(18)
@talk
def fun2(age):
print(f'我是精神小伙,我今年{age}岁了')
fun2(18)
迭代:一代一代的更新
迭代的特点:每一次迭代得到的结果都是下一次迭代的初始值,比如python版本,手机系统
可迭代对象:字符串,列表,元组,集合,字典
可迭代对象的表现形式为:内置了iter方法的数据 ,都属于可迭代对象
a='1234' #这只是一个元素
a1='1','2','3'
b=[1,2,3]
c=(1,2,3)
d={1,2,3}
y={'name':'陌上'}
v=123
print(a1.__iter__())
print(b.__iter__())
print(c.__iter__())
print(d.__iter__())
print(y.__iter__())
# print(v.__iter___()) #pycharm会给你补全这个方法 就是一个可迭代对象 硬打就不是
可迭代对象转变成迭代器
声明迭代器:
语法1:
变量名=可迭代对象.__iter__()
语法2:
变量名=iter(可迭代对象)
变为迭代器后,就可以用next方法把里面的数据一个个取出来使用
迭代器的表现形式为:
内置了__next__方法的数据就是迭代器
next方法是对迭代器进行取值:
#语法一
迭代器名称.__next__()
#语法二:
next(迭代器名称)
num=[1,2,3,4]
res=num.__iter__() # 也可以这样写iter(num)
print(res.__next__()) #也可以这样写next(res)
print(res.__next__())
print(res.__next__())
print(res.__next__())
# print(res.__next__()) #报错 超出取值范围
for 循环的原理,也就是把数据转成一个迭代器,然后把里面的数据一个个的取出来使用
生成器:可以理解为自定义迭代器,当一个函数内有yield这个关键字的话,那么这个函数就是生成器
生成器的返回的是迭代数据,需要使用迭代取值的方式获取,数据生成是边生成边迭代
yield–这个可以返回数据,但是返回之后不会停止函数的执行而是进入暂停状态,等待下一次的调用取值就会继续往后面执行
# def m():
# for i in range(1,11):
# print(f'这是第{i}碗')
# m()
#生成器函数
def fun():
for i in range(1,11):
yield f'这是第{i}碗'
print('好好吃')
f=fun() #把生成器对象 赋值给一个变量
print(type(f)) #generator 生成器
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
# print(f.__next__()) #报错 超出取值范围
#用生成器表达式
名称=(返回值 for 变量 in 可迭代对象)
noddle=(f'这是第{i}碗' for i in range(1,6))
print(noddle) #生成器的内存地址
print(type(noddle)) #类型是生成器
print(next(noddle))
print(next(noddle))
print(next(noddle))
print(next(noddle))
print(next(noddle))
#生成器了解即可 目前不用写 目前阶段用不上 后面学习爬虫的时候会用到生成器表达式
了解原理 1.指定规则 2.生成数据 就可以了
#代码实现目前知道即可,不理解完全OK 理解的了最好
#具体使用不用太纠结 先知道这个东西 到时候学爬虫的时候 会具体用到
文件路径 --> 文件存储的位置
绝对路径=完整的路径,可以从盘符开始找到文件(c:--盘符)
生活中:陕西省宝鸡市扶风县**栋**楼**门牌号
电脑中:C:\Users\hp\Desktop\文件操作与迭代器生成器.md
相对路径=简短路径,有参考对象,默认从当前文件夹开始
生活中:扶风县**栋**楼**门牌号
电脑中: 文件在同一个文件夹时,直接写文件名
相对路径:
./ --表示当前文件夹(可以省略不写)
./文件操作与迭代器生成器.md == 文件操作与迭代器生成器.md
../ -- 表示返回到上一层文件夹
../文件操作与迭代器生成器.md --返回这个文件的上层文件夹 Desktop
../../文件操作与迭代器生成器.md --返回的上上层文件夹 hp
用python代码来操作电脑里的文件(txt,exe,md,py,mp3,doc)--文本/图片/音频...
文件的数据类型:
t:text 文本数据 文件操作默认就是文本数据
b:byte 以字节码的方式来操作数据--目前还不需要使用 后面学到网络编程/爬虫的时候会用
wb:以字节码的方式写入数据
wt:以文本的方式写入数据
rb:以字节码的方式读取数据
文件操作的三要素:
1.打开文件
2.操作文件
3.关闭文件
文件操作语法格式1:
文件名=open(文件路径\文件名,操作模式,encoding='utf-8') #如果不写文件路径 默认就会在当前文件夹
f.操作模式()
f.close()
该语法格式在操作结束时,必须每次对文件进行关闭,否则会引起内存泄漏
f 是作为文件对象 名字是不固定的,但是一般都叫f
文件操作模式:
w:write 写入数据,如果文件里有数据 会被覆盖 如果没有这个文件就会新建
a:append 追加数据,如果文件里有数据,不覆盖而是追加到后面
r:read 读取数据
f.read():读取所有数据,也可以在括号里面放参数,指定读取的数据
f.readline():读取一行数据,也可以在括号里面放参数,指定读取的数据,但是超出一行的内容,也是只会读取一行
f.closed --> 判断文件是否已经关闭 True关闭 False没关闭
f.writable() --> 判断文件是否可写 True可写 False不可写
f.readable() --> 判断文件是否可读 True可读 False不可读
#wrtie没有这个文件会写入数据
f=open('伊诺.txt','w',encoding='utf-8')
f.write('伊诺真好')
# print(f.writable()) #判断文件是否可写
f.close()
# print(f.closed) #判断文件是够关闭
#wrtie有这个文件是会覆盖之前 的数据
# f=open('伊诺.txt','w',encoding='utf-8')
# f.write('伊诺真美\n')
# f.close()
#append 不会覆盖 是添加新内容 也是用f.write()写入数据
# f=open('伊诺.txt','a',encoding='utf-8')
# f.write('你们真帅')
# f.close()
#read
f=open('伊诺.txt','r',encoding='utf-8')
print(f.read()) # 默认读完
# print(f.readable()) #判断文件是否可读
f.close()
f=open('伊诺.txt','r',encoding='utf-8')
print(f.read(3)) #也可以指定数据读
f.close()
#f.readline()
f=open('伊诺.txt','r',encoding='utf-8')
print(f.readline()) #读取一行数据
f.close()
#绝对路径 在我这里可以用 但是你的电脑用不了
f=open(r'C:\Users\hp\Desktop\陌上.txt','w',encoding='utf-8')
f.write('回家哈哈哈哈')
f.close()
#相对路径 推荐用相对路径
f=open('../嘿嘿.txt','w',encoding='utf-8')
f.write('嘿嘿嘿嘿')
f.close()
文件操作语法格式2:为了避免文件操作没有关闭导致内存泄漏,有种更推荐的写法,叫 with open.这个写法会文件操作结束后自动关闭文件
with open(文件路径\文件名,操作模式,encoding='utf-8') as 名字:
名字.操作模式()
#该模式会对文件自动关闭
# with open('first.txt','w',encoding='utf-8') as f:
# f.write('陌上\n周茹华\n地狱¥管家\n张杰\n梁凡\n')
# with open('陌上.txt','a',encoding='utf-8') as f:
# f.write('祝你们都优秀\n吃饭嘎嘎香')
# f.write('身体健康,学业有成,万事如意')
with open('陌上.txt','r',encoding='utf-8') as f:
res=f.read()
print(res[3:])
with open('陌上.txt','r',encoding='utf-8') as f:
res1=f.readline() #读一行 不能指定读取某一行的内容
# print(res1)
print(res1[1])
print(res1[0])
# with open('陌上.txt','r',encoding='utf-8') as f:
# res2=f.readline(1) #也可以指定数据读取 超出一行的内容,也是默认读完这一行
# print(res2)
http://c.biancheng.net/python/file
本节课文件操作内容需要拓展可以翻这个帖子
复习博客 http://c.biancheng.net/view/5419.html
迭代器 http://c.biancheng.net/view/2393.html
生成器 http://c.biancheng.net/view/2270.html
迭代器--把一个有很多数据的容器整理好,把里面的数据一个个的取出来使用
生成器--自定义的迭代器,主要作用是用来制定规则,生成数据
一个函数里有哪个关键字 他就是生成器?--yeild
文件操作--用python来读/写电脑里的文件
1.打开文件
2.操作文件
3.关闭文件
操作模式:
r:read 读取文件
w:write 写入文件--如果源文件有数据 会覆盖
a:append 追加文件--如果源文件有数据 不会覆盖而是追加
上下文管理器:会根据代码上下文,自动进行操作 文件操作中 会运行后自动的关闭文件
with open('文件路径+文件名','操作模式',encoding='utf-8') as f:
f.write('写入数据')
f.read() #读取数据
with open('复习.txt','w',encoding='utf-8') as f:
f.write('复习一下') #写入模式为w
with open('复习.txt','a',encoding='utf-8') as f:
f.write('今天是个好日子')
with open('复习.txt','r',encoding='utf-8') as f:
print(f.read()) #读取 操作模式改为r
什么是模块:
模块本质就是一个python文件(.py文件)
当python文件作为一个模块是,文件名就是模块名
demo.py(模块) --demo是模块名
使用模块的作用:
可以通过导入模块的方式,直接调用他模块里的代码,功能,可以更灵活的实现和使用,添加各种效果
变量=存储一个/多个数据
函数=存储多段代码
模块=所有东西都可以进行存放(变量,函数),本质就是一个python文件
当我们导入了一个模块后,就可以使用这个模块里的所有代码:里面的变量和函数
python自带的 不需要提前下载 直接导入使用
import time #时间模块
import random #随机数模块
import os #系统模块
不是python自带的,而是其他开发者写好上传的,使用之前需要先下载再导入使用
pywin32--windows编程
pygame--游戏开发
requests-->爬虫
pip-->python 自带的下载器
python默认下载库就是使用pip,如果python环境没配置好,pip就使用不了 -->修复/重装
#如何下载第三方模块
在cmd中输入下面代码:
pip install 你要下载的库名
pip install pygame
#升级pip 有时候pip的版本太低 新的库下载不了
(注意:不要动不动就更新pip,有时候过新pip也是无法下载的,所以如果能下载的话,就不要更新)
python -m pip install --upgrade pip -i https://pypi.doubanio.com/simple
因为模块基本都是部署在国外,国内下载访问就会比较慢
就可以通过镜像代理,加速下载
阿里云:http://mirrors.aliyun.com/pypi/simple/
中国科技大学:https://pypi.mirrors.ustc.edu.cn/simple/
清华大学:https://pypi.tuna.tsinghua.edu.cn/simple/
豆瓣镜像地址:https://pypi.douban.com/simple/
例:
#通过镜像代理加速,下载第三方模块:
pip install 你要下载的库名 -i 镜像代理的位置
pip install pygame -i https://pypi.douban.com/simple/
#如果下载会超时的话导致下载不成功 可以这样写 直接复制以下代码
pip install 你要下载的模块名 --default-timeout=100 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pygame --default-timeout=100 -i https://pypi.tuna.tsinghua.edu.cn/simple
卸载第三方模块
在cmd中输入下面代码:
pip uninstall 模块名
pip uninstall pygame
开发者自己定义自己写的模块
如果想要把一个python文件作为一个模块进行使用的话,尽量遵守命名规则
模块名规范:
1.见名知意
2.纯小写+下划线
3.一定不要用中文命名,在导入模块的时候,就很容易出现问题
例:
user_longin #用户登录模块
user_register #用户注册模块
模块使用流程:
1.导入模块
2.调用/使用模块
模块的使用顺序:
1.导入模块中的单个功能
2.调用模块中的内容
3.优先自己的功能
4.调用模块里面的
导入模块:
import 模块名
import time
import demo
import 导入的意思
使用模块:
import 模块名
print(模块名.变量名) #调用模块里的变量
模块名.函数名() #调用模块里的函数
import test
print(test.a)
test.fun()
print(test.talk()) #打印返回值所以需要print
导入模块的单个函数或者变量:
from 模块名 import 函数名
from 模块名 import 变量名
print(b) #直接写变量名 不需要写模块名
student() #调用函数 直接写就好,不需要写模块名
优点:避免不必要的内存资源开销 减少代码量
缺点:可能会出现同名覆盖的情况(容易出现名字混淆) 优先自己模块的内容
如果模块名过长或不好记,通过as关键字 可以给它取别名
import 模块名 as 别名
import user_register as register #以后这个模块名就叫做register
python导入模块的时候,解释器会把模块中的内容先读取一遍:
1.读取模块中的全部内容
2.会生成对应的名称空间,这个名称空间的名字会跟模块名一致(会把模块中的变量,函数存进去)
3.等待程序的调用-->模块名.变量名/函数名
python中的__name__属性:
如果当前文件作为一个执行程序的来操作的话,那么__name__的返回值为__main__
如果当前文件作为一个模块来操作的话,那么__name__的返回值为模块名(文件名)
#在pycharm里面,输入main按下回车键/tab,就会自动帮你补全代码
if __name__ == '__main__':
代码 #这里面的代码,当文件作为一个执行程序的时候,才会执行
例子:有些人就只会窝里横,在家里老子就是天,在外面就畏畏缩缩
当返回值为__main__,表示在家里,老子想怎么样就怎么样(想输出就输出)
当返回值为模块名时,表示在外面,畏畏缩缩的,什么也不敢干
python通过main和name可以获取程序的状态:
1.python的main和其他语言的main不一样,不是作为程序的入口
2.一个python文件,如果他的__name__为__main__,那他就是启动文件,否则他是一个模块
3.基于这个特性,可以把一些非必要执行的代码,放到main判断中,只有文件是以程序身份来执行的时候,才会运行里面的代码
导入规范:
不推荐一行导入多个模块(太长,不方便查看)
import time,random,os
推荐多行导入
import time
import random
import os
导入顺序:
1.最先导入内置模块
2.然后导入第三方模块
3.最后导入自定义模块
例:
import time
import random
import pygame
import requests
import demo
#无论你自己看 还是别人 看这个导入模块 就比较清晰
模块=文件
包=文件夹
包的概念:
包就是一个特殊的文件夹,管理模块使用的,把一些功能相同的模块放在一起,方便我们的维护与管理
验证登录 --8
数据 --10
基础设置 --2
包的创建方式:
在pycharm中--右键项目文件夹--new--python package
创建好包之后,会自动生成一个名为__init__.py的文件,这个文件就是一个负责管理包的模块 init-->初始化
__init__在导入包的时候会自动执行里面的内容
在__init__文件中可以写入包中模块的使用说明.配置信息
包的导入使用:
from 包名 import 模块名
from login import qq
print(qq.name)
qq.fun()
导入包内模块的单个功能
from 包名.模块名 import 变量名/函数名
from login.qq import fun
from login.qq import name
fun()
print(name)
模块的本质-->一个python文件
模块名-->文件名(不带后缀)
text.py-->模块名是text
导入使用模块
import 模块名
import time
#使用模块中的变量
模块名.变量名
#使用模块中的函数
模块名.函数名
模块分为三类:
1.内置模块:python自带的
2.第三方模块:>其他开发人员写的,要使用的时候需要进行下载(pip)
1.打开cmd,2,pip install 模块名 -i 镜像代理位置
3.自定义模块:开发者自己写的模块
如果说你自己写的一个python文件想要作为一个模块来使用,那么要遵循模块的命名规范
给模块取别名 -- as
import 模块名 as 别名
__name__属性:判断当前的文件是以模块使用还是执行程序来使用
当返回值__main__,这个文件是作为执行程序来使用
当返回值模块名,这个文件是作为模块来使用
if __name__ == '__main__':
代码 #里面的内容只有当前文件是执行程序才会运行
包的本质-->一个特殊的文件夹
包在在创建时会自动生成一个名为__init__.py文件
init文件主要是管理包中的各个模块,这个文件在导包的时候会自动执行里面的内容
包是可以统一管理各个模块,方便后续的维护操作
from 包名 import 模块名
#导入时间模块
import time
#获取1970.1.1距离现在过去了多少秒
print(time.time())
#可以计算程序执行的时间长短
start=time.time()
def fun():
print('我模拟的是一个程序的运行')
fun()
#让程序休眠,里面的参数是一个数值类型(整型,浮点型)的数据
# time.sleep(3)
end=time.time()
print(end-start)
'''
def fun():
print('我这是一个很牛的功能')
time.sleep(3) 会员就慢 那你开了 就可以给你加速
print('我是一个很牛的功能,但是我运行的好像有点慢,说不定你充点钱就变快了')
写了一个功能,人为的加了sleep命令,让程序运行时间拉长
形成了一种很慢的现象,以此要求对方.得加钱/优化项目的时候,再过给你点时间,时间变得更快
'''
#3.获取格式化时间
#获取年月日
print(time.strftime('%Y-%m-%d'))
#获取年月日 星期几
print(time.strftime('%Y-%m-%d %A'))
#获取时分秒
print(time.strftime('%H:%M:%S'))
#获取时分秒 上午还是下午
print(time.strftime('%H:%M:%S %p'))
#以斜杠分割 月份日期年份
print(time.strftime('%x %X'))
print(time.strftime('%X %x'))
#将当前时间以结构化的方式进行展示
print(time.localtime())
#导入随机数模块
import random
#在0-1之间的随机小数
print(random.random())
#在指定整数范围内的随机整数 random.randint(起点,终点) 包含终点的值
print(random.randint(1,3))
#在指定范围内的随机小数
print(random.uniform(1.5,4.5))
res=random.uniform(1.5,4.5)
print('%.2f'%res)
game=['剪刀','石头','布']
#随机在列表/元组中输出一个元素
print(random.choice(game))
#随机打乱列表 只能打乱列表
num=[1,2,3,4,5,6,7,8,9]
print(num)
random.shuffle(num)
print(num)
#通过随机模块,可以做一些小项目-->猜拳 ,斗地主,验证码,抽奖
#生成一个四位字母验证码
def fun():
#声明一个空的字符串,用来保存获取到的每个字母,进行拼接
msg=''
for i in range(4):
# 65-90:大写A到Z之间的所有字母对应的ascii码的序号
msg+=chr(random.randint(65,90)) #生成一个65-90之间数字,并转为字符
return msg
print(fun())
#os模块,操作系统模块,主要操作当前项目的文件
import os
# os.system 打开cmd
# os.system('start cmd') #打开cmd
# os.system('start calc') #打开计算器
# os.system('start osk') #打开屏幕键盘
# os.system('start mspaint') #打开画图工具
# for i in range(5):
# os.system('start cmd')
#获取到当前文件所在的位置
print(os.getcwd())
#在当前文件中新建文件夹 os.mkdir(文件夹名)
# os.mkdir('classmate')
#删除文件夹,只能删除空白的文件夹,如果文件夹中有内容,就不能删除
# os.rmdir('classmate')
#切换当前位置,切换程序的执行程序
# os.chdir('classmate')
# print(os.getcwd())
#删除文件
# os.remove('a.py')
#给文件重命名 os.
# os.rename('a.py','b.py')
# os.rename('b.py','c.txt') #一般不会重命名的时候去改后缀 改了后缀的话会发生文件异常 不建议强制改文件类型
#判断文件或者文件夹是否存在
print(os.path.exists('os_demo.py'))
#输出当前文件夹里所有文件名
print(os.listdir())
#系统模块 system -->深入的功能目前不需要使用
import sys
#获取你的python环境变量 -->python安装位置+项目位置
print(sys.path)
#获取你的程序位置
print(sys.argv)
#获取python版本的信息
print(sys.version)
#win32不是你的操作系统位数 获取操作系统架构信息
print(sys.platform)
'''
json模块
json是一种文件的存储格式,主要作用就是在保留原来类型的情况下,保存数据
一个数据用json可以确保 存之前是什么类型 取出来还是什么类型
json就是一种让你的文件可以保留原来类型的文件格式
'''
import json
#普通存入一个文本的话 数据类型必须为字符串
# stu=['张杰','薛之谦','周深','范丞丞','邓紫棋','周杰伦','林俊杰']
# with open('陌上.txt','w',encoding='utf-8') as f:
# f.write(str(stu))
#
# with open('陌上.txt','r',encoding='utf-8') as f:
# res=f.read()
# print(res)
# print(res[0])
# print(res[1])
# print(res[2])
# print(res[3])
#用json存
info={'name':'陌上','age':18,'money':95.53}
#json.dumps(info) 把数据转为json格式
# json_data=json.dumps(info)
# print(json_data)
#读取json格式数据
# data=json.loads(json_data)
# print(data)
# print(type(data))
#将数据写入到json文件中
with open('msg.json','w',encoding='utf-8') as f:
json.dump(info,f) #把info这个字典传进去,有两个参数,第一个是你想要存的数据,第二个参数是文件
with open('msg.json','r',encoding='utf-8') as f:
find=json.load(f) #读取msg.json文件
print(find['name'])
print(type(find))
print(find)
stu=['张杰','薛之谦','周深','范丞丞','邓紫棋','周杰伦','林俊杰']
with open('msg2.json','w',encoding='utf-8') as f:
json.dump(stu,f)
with open('msg2.json','r',encoding='utf-8') as f:
find1=json.load(f)
print(find1[0])
print(find1[1])
mvc开发模式-->开发时的一种设计理念
Modle--模块层-->主要处理数据相关的东西(数据库,json)
View--视图层-->主要处理用户体验,给用户看的东西
Controller--控制器层-->主要处理后台功能,实现各种功能
以前开发一个项目的时候并没有一样具体的分工,导致有的时候就很乱,出现了bug各种甩锅,所以有前辈总结了MVC的开发模式
就是在开发项目时为M,v.C三层,每层都有自己的任务,互有联系,但互不干涉,开发人员只需要专注好自己负责的部分就好
出现了问题,也更好的找到问题所在
这次做项目的时候,用的知识点都时以前学过的
但是这次的开发标准就比较正式
区分好几个文件夹 每个文件夹有不同的功能
文件夹里的文件名,变量名,函数名都会更加讲究规范
函数对象--把函数当成一个普通的容器来使用
1.用函数来赋值
1.1.把函数本身复制给一个变量,变量就相当于函数的分身
a=print #把print函数的功能复制了一份给了a,a以后也可以用来输出
1.2.把函数的返回值赋值给一个数据
def fun():
return 666
res=fun()
print(res)
2.可以把函数放到一个数据容器里(列表,元组,字典,函数)
def fun():
return 666
li=[1,2,fun]
demo={1:fun}
3.可以用函数作为返回值(闭包)
4.可以函数作为参数 3+4 -->装饰器
def add_food(a):
def beer(*args,**kwargs):
a(*args,**kwargs) #调用传进来的函数
print('夏天到了要来打啤酒')
return beer
@add_food
def eat():
print('今天吃小龙虾')
eat()
@add_food
def eat_1():
print('今天吃小火锅')
eat_1()
名称空间:在python中一块专门来存储名字的区域,默认情况下有三块名称空间
内建名称空间:存储python的内置函数,内置变量,他会随着python程序启动而生成
全局名称空间:存储用户定义外层的名字(变量名,函数名) 它会随着python程序启动而生成
局部名称空间:存储用户在函数内的名字(变量,形参,函数),它会随着函数的调用而生成
作用域:一个数据能够被使用的范围
全局-->整个程序里都可以使用
局部-->程序里的部分位置才能使用(函数内)
global -->提权 把一个数据从局部变为全局
nonlocal-->私有化,把一个数据降权 局部变量再度局部化
闭包:在一个嵌套函数中,用内层函数操作外层函数得到的数据,属于间接修改
def 外函数名(参数):
def 内函数名():
操作
return 内函数
单纯写闭包其实是没啥意义 闭包一般是为了实现装饰器来使用
装饰器:在不修改源代码/调用方式的情况下,给一个函数间接添加好功能
实现原理就是通过闭包,把要添加的功能的函数传递进来 在内层函数中调用, 并在内层函数里新增新功能代码,最后把内层函数返回出去-->得到了被添加好功能的函数
写好的装饰器可以通过@语法糖 放到要添加功能的函数名上,就可以实现功能追加
迭代器iter:
对一堆数据进行更新迭代的操作:
说人话:把很多的数据,有序的取出来使用
for循环的原理:把一个有很多的数据的对象转换成迭代器,再把里面的数据一个个的取出来使用
生成器yield:
是一个自定义的迭代器,在函数里有个关键字yield
生成一个自定义的迭代器 自己指定规则,生成指定数据
生成器一般是直接用生成器表达式来创建
文件操作:
用python代码来操作电脑文件
文件操作三要素:
打开文件 操作文件 关闭文件
为了避免忘记关闭为晚间 一般用with上下文管理器来写代码
with open
操作模式:
w:写入 #如果有数据会覆盖
a:追加 #如果有数据不覆盖
r:读取 #查看数据
with open('路径+文件名','操作模式',encoding='utf-8') as f:
f.wirte(写入数据) #w
f.read() #r 读取数据
模块:所谓的模块,指的其实就是一个python文件
模块的好处就是避免重复-->有的功能别人已经给你写好了,你就不用写,拿来用就好
模块分为三种:
内置模块-->random,time.os,sys,json->python自带的不需要提前下载
第三方模块-->requests,pygame-->别人写好的 要先下载才能使用
自定义模块-->用户自己写的模块
下载第三方模块使用pip工具-->在cmd中输入 pip install 库名
pip install requests
模块的基本使用:
1.导入模块-->import
import 模块名
import time
import 模块名 as 别名
import win32con as con
2.使用模块
模块名.变量名 #使用模块中的变量
模块名,函数名 #使用模块中的函数
当你导入模块发生的事:
1.先把模块文件运行一遍,确保没有问题
2.生成一个名称空间,把模块里的名字存进去,名称空间就是模块的名字
3.让当前运行程序连接名称空间,后续就可以通过 模块名. 的方式使用里面的数据
如何区分一个python文件是模块还是执行程序
通过__name__
python有一个内置变量叫__name__,他只有两种结果
1.该文件作为模块运行时.__name__的结果是模块名
2.该文件作为执行程序时.__name__的结果是__main__
因此可以把一些测试代码 放到这个main判断中,当文件是执行程序的时候才会运行
if __name__ == '__main__':
代码
包:文件夹,把一些功能统一的模块放到一起,更好管理,里面会生成名为__init__.py的文件
当导入这个包里的模块时,init的代码也会自动执行,所以可以把一些配置信息.使用说明 写到init里
常用模块:
time:时间模块
random:随机模块
sys:系统模块,python解释器在打交道
os:操作系统模块,.文件所在的操作系统打交道
json:序列化文件模块 更好的保存数据的一种文件格式
强调:一定不要把python文件名命名为内置模块名!!!