目录python
编程语言是人类与计算机交流的介质git
编程就是程序员经过某种编程语言所编写的一堆文件程序员
为了让计算机帮助人类工做算法
编程语言是用来和计算机交互的,可是计算机只认识0和1编程
直接和硬件交互(用0和1和计算机沟通)api
优势:执行效率高网络
缺点:开发效率低闭包
直接和硬件交互架构
优势(相较于机器语言):开发效率高app
缺点(相较于机器语言):执行效率低
间接和计算机硬件交互
记录下来,所有说完才能翻译.文件编译成另外一个obj文件.再和计算机沟通获得结果,把代码翻译成机器语言,经过编译器(汇编语言/机器语言写的)
优势(相较于解释型语言):执行效率高
缺点(相较于解释性语言):开发效率低
说一句翻译一句
优势(相较于编译型语言):开发效率高
缺点(相较于编译型语言):执行效率低
翻译成机器语言,通常是经过解释器(编译型语言写的)
咱们写程序必定是程序运行的越快越好,咱们应该用编译型
控制硬件
算术运算和逻辑运算
计算机只认识0和1(高低压电频)
优势:速度快
缺点:断点即消失
优势:容量大,永久保存
缺点:速度慢
固态硬盘不须要平均延迟时间,RAM(断电即消失) SSD(断电不消失+算法(数学))基于电存储
输入信息,(键盘,鼠标等)
输出信息, (显示屏,打印机等)
输入输出信息,(U盘)
32位一次接受32个字节
64位一次接受64个字节
具备向下兼容性(好比说,64位兼容32位,32位不兼容64位)
开机就是告诉计算机操做系统的位置,存储在CMOS存储期内
你重装系统的时候为何要插U盘: 更改操做系统的路径
机械硬盘上存储的都是0和1
机械手臂: 读取数据
磁道: 存储数据
扇区: 多个磁道组成一块,起始位置
寻找数据的时间:
平均延迟时间: 机械手臂到磁盘的时间 5ms (固态硬盘没有这个时间)
平均寻数据的时间: (0 + 8.3) /2
7200r/min
文件是操做系统提供的虚拟单位
应用程序就是一大堆文件
操做系统本质仍是一个软件
操做系统就是把对计算机的复杂指令简单化(对CPU的指令)
应用程序依托于操做系统
操做系统依托于临时操做系统
其余的步骤都是如出一辙的
引用木桶效应(能够百度)
由于网络延迟远远大于程序的运行速度,这个时间能够户罗不计。
变量是用来描述世间万物的状态
height_of_nick = 150, 下划线式
HeightOfNick = 150, 驼峰体
不变的量,常量本质上也是个变量,只不过变量名全大写约定俗成为了常量,之后不要去改变他
有n个变量名指向一个变量值A,则A的引用计数为n
当变量的引用计数为0的时候,python解释器会自动回收该变量的内存空间
[-5, 256]之间,当python解释器打开的时候就已经开辟内存空间存在,不会受垃圾回收机制影响
优势:运行一句执行语句
缺点:关闭即消失
优势: 一直存在
缺点:所有写完才能调试BUG
交叉赋值
x, y = y,x
链式赋值
x=y=z= 10
解释 ; 让代码在python解释器运行的时候不被解释,即让他无心义
单行注释: '使用单引号' 多行注释: ''' 可 以 换 行 '''
数据类型: 不一样种类的变量值用不一样的数据类型描述
age = 18;age = int(18);int('18')
age = 18;age1 = 19 # 不建议使用 print(age,age1) age,age1 = 18,19 # 解压缩
+-*/ % // **
( a = 1log
方法,导入import cmath
库年龄/身份证号码/身高/体重等
salary=3.2;salary=float(3.2);float('3.2')
+-*/ % // **
( a = 1log
方法,导入import cmath
库能够用来表示薪水等
name = 'nick';name = "nick" name = str('nick') name = ''' nick nick ''' name = """ nick nick """ x = str(10) # '10'
s1 = 'nick' s2 = 'handsome' s1 + s2 s3 = 10 # nickhandsome s1 + str(10) # nick10 # int(s1) + s3 s1 * 5 # 'nicknicknicknicknick'
ctrl+鼠标左键 进入源码模式
nick_info = ['nick',180,140,['read','run','music']] nick_info[-1][1] # 'run' # 仅作了解 lis = [1,2,3] lis2 = [4,5,6] print(lis+lis2) print(lis*2) # [1, 2, 3, 1, 2, 3]
nick_info_dict = {'name':'nick','height':180} nick_info_dict['height']
除了0/None/空/False以外全部的数据类型(全部你能看到的东西)都自带布尔值为True
一次性取多个值,解压缩的对象有多少个元素,则必须拿多少个
lis = [1,2,3] x1,x2,x3 = lis # 1,2,3 # 不会用 x1,_,x3 = lis # 1,_,3 *_,x3 = lis # _,_,3
input() # 等待用户输入,若是用户不输入,程序不会结束运行 input接收的值不管如何都是字符串 ''' x = input('请输入你想要的输入的数字:') print(type(x)) print(x) x = int(x) + 1 # x = eval(x) # 除了字符串之外均可以转换,不建议使用 print(x) '''
raw_input() # 与用户交互和python3中的input如出一辙 input() # 与用户交互,必须得指定输入的类型,输入什么类型拿到什么类型
name = 'nick' print('name:{}'.format(name))
name = 'nick' print(f'name:{name}') # :.2f 保留两位小数
+-*/ % // **
= += -= *= /= %= //= **=
> >= < <= == !=
(A is not B == not A is B)
''' if <条件>: <代码块> '''
伪代码: 大概知道代码的意思,可是这种代码没法运行
''' if <条件>: <代码块1> else: <代码块2> '''
''' if <条件1>: <代码块1> elif <条件2>: <代码块2> ... else: <代码块3> '''
''' if <条件1>: if <条件2>: <代码块> '''
if 条件: # TODO pass
不可控, 循环一切
跳出本层循环,跳出循环
跳出本次循环
循环没有被break终止才会执行
可控, 循环容器类型元素 + 字符串(可迭代数据类型)
0,1,2,3,4,5,6,7,8,9 10 .....99 100 1000 10000
0 1 10 11 100
10101
$$
2^41 + 2^30 + 2^21 + 2^10 + 2^0*1 = 21
$$
低电压表示 0
高电压表示 1
低高低高
0101 a
x = 10
, x = int('10')
x = 10.1
, x = float('10.1')
name = 'nick' # \n 换行 # \t 缩进,4个空格 # \r+end='' 覆盖上一次打印 name = r'\n\ta' # 取消\n和\t的做用 name = '\\n\\ta' # 取消\n和\t的做用
有索引的就是有序,无索引的就是无序
值变id不变的是可变类型;值变id变的是不可变
1. 定义方式: {}内以逗号隔开多个元素(不能为可变数据类型)
条件判断后触发,通常不单独使用
age = 18 # 答案 count = 0 # 游戏次数控制 prize_dict = {0: '布娃娃', 1: '变形金刚', 2: '奥特曼', 3: '<Python从入门到放弃>'} # 核心代码 while count < 3: inp_age = input('请输入你的年龄>>>') # 与用户交互 # 判断用户是否骚扰(超纲:判断用户输入的是否为数字) if not inp_age.isdigit(): print('傻逼,你的年龄输错了') continue inp_age_int = int(inp_age) # 核心逻辑,判断年龄 if inp_age_int == age: print('猜对了') print(prize_dict) # 打印奖品 # 获取两次奖品 for i in range(2): prize_choice = input( '请输入你想要的奖品,若是不想要,则输入"n"退出!!!') # 与用户交互获取奖品 # 判断是否须要奖品 if prize_choice != 'n': print(f'恭喜你得到奖品: {prize_dict[int(prize_choice)]}') else: break break elif inp_age_int < age: print('猜小了') else: print('猜大了') count += 1 # 成功玩一次游戏 if count != 3: continue again_choice = input('是否继续游戏,继续请输入"Y",不然任意键直接退出.') # 交互是否再一次 # 判断是否继续 if again_choice == 'Y': count = 0
深浅拷贝只针对可变类型
lt = [1,2,3,[4,5,6]] lt2 = lt # 当lt2为lt的拷贝对象时,lt内部任意数据类型的对象变化,lt2都变化
lt = [1,2,3,[4,5,6]] import copy lt2 = copy.copy(lt) # lt2 = lt.copy() # 当lt2为lt的浅拷贝对象时,lt内部可变数据类型变化,lt2也随之变化;lt内部不可变数据类型变化,lt2不变
lt = [1,2,3,[4,5,6]] import copy lt2 = copy.deepcopy(lt) # 当lt2为lt的深拷贝对象时,lt内部任意数据类型的对象变化,lt2都不变化
try: 1/0 except Exception as e: print(e) finally: print(1) # assert assert 1 == 1 # 知足条件跳过这一行 ; 不知足报错 # raise raise 错误类型() # 抛出异常
可变 | 不可变 |
---|---|
列表/字典/集合 | 整型/浮点型/字符串/元组 |
有序 | 无序 |
---|---|
字符串/列表/元组 | 字典/集合 |
一个值 | 多个值 |
---|---|
整型/浮点型/字符串 | 列表/元组/字典/集合 |
# 1. 打开文件 f = open(file_path, 'r') # 2. 读写操做 f.read() / f.write() # 3. 关闭文件 f.close()
二进制和字符之间的转换过程 --> 字符编码
ascii,gbk,shit,fuck 每一个国家都有本身的编码方式
美国电脑内存中的编码方式为ascii ; 中国电脑内存中的编码方式为gbk , 美国电脑没法识别中国电脑写的程序 , 中国电脑没法识别美国电脑写的程序
如今硬盘中躺着 ascii/gbk/shit/fuck 编码的文件, 他们的编码格式已经没法修改了, 因此内存中出现unicode编码, 内存中的unicode编码方式能够识别 ascii/gbk/shit/fuck 编码的文件
用unicode编码方式运行了 ascii/gbk/shit/fuck 编码的文件, 最后仍是要装入硬盘, 装入硬盘早期用unicode存进去,可是 他在识别ascii的时候, 会把8位数字转换成16位数字存入硬盘, 浪费空间, 因此出现了utf8(与unicode对应,而且压缩unicode编码的字符)
utf8 能识别其余国家的编码,只识别unicode, utf8目前还不能放在内存,. 可是如今写的代码都是utf8, 历史遗留ascii/gbk/shit/fuck 编码的文件早晚消失/淘汰,要么被转换成utf8格式.因此早晚有一天内存中也是utf8.
代码详情 | Python2执行状况 | Python3执行状况 |
---|---|---|
coding:gbk print('中') 终端:utf8 |
乱码 | 不乱码 |
coding:utf8 print('中') 终端:utf8 |
不乱码 | 不乱码 |
coding:gbk print(u'中') 终端:utf8 |
不乱码 | 不乱码 |
coding:utf8 print(u'中') 终端:utf8 |
不乱码 | 不乱码 |
用文件指定的编码方式存储定义后的变量
若是文件指定编码为'gbk' ,那就会以gbk的形式存储变量, 原本打印的是0和1,可是终端会自动对你的0和1安装终端默认的编码转换成字符 ,若是终端的默认编码是utf8 ,乱码; 若是终端默认编码是gbk,不乱吗
若是定义变量前加上u,coding:xxx不会对他形成任何影响, 由于会用unicode编码存储变量, 终端是任何类型的编码均可以识别
用unicode编码方式存储定义后的变量
之后写文件以什么格式存储,就以什么格式读取
r : 只读
f.read()
w: 清空后写入(文件不存在自动建立)
f.write()
a: 追加(文件不存在自动建立)
f.write()
文本模式:t
二进制模式:b
t/b没法单独使用,只能和r/w/a一块儿使用
with open() as f: # 自动关闭
pip instlal pyinstaller
切换路径到文件夹(文件夹包含img.ico和test.py这两个文件)
pyinstaller -i img.ico -F test.py
with open('test.py','r',encoding='utf8') as fr,\ open('test_swap.py','w',encoding='utf8') as fw: data = fr.read() # data逻辑修改 fw.write(data) import os os.remove('test.py') os.rename('test_swap.py','test.py')
with open('test.py','r',encoding='utf8') as fr,\ open('test_swap.py','w',encoding='utf8') as fw: for i in fr: # i逻辑修改 fw.write(i) import os os.remove('test.py') os.rename('test_swap.py','test.py')
def 函数名(参数1,参数2,...): return 返回值
没有参数的函数
有参数的函数
pass
return 除了能返回值 ,终止函数
返回多个值,用元组形式返回
函数名()
具备描述意义
从左到右一个一个写
位置形参具备默认值, 默认形参必须在位置形参后面
具体的数据类型
从左到右一个一个给形参传值
按照形参名传值, 关键字实参在位置实参后面
*args用元组的形式接收多余的位置实参,
打散元组而后将打散的值一个一个传值给形参
**kwargs用字典的形式接收多余的关键字实参
打散字典而后将打散的值传给形参
dic = {'a':1,'b':2} a=1,b=2
函数内套函数
def f1(): def f2(): pass
命名空间是用来组织和重用代码的。
python解释器启动的时候生成,如 len/int/dict
文件执行的时候生成
函数调用的时候生成
内置-->全局-->局部
从当前开始 --> 局部-->全局-->内置
全局+内置空间定义的变量
x = 1 def f1(): x = 3 f1() print(x) # 1 x = 1 和 x = 3的两个x毫无关系
局部空间定义的变量,不一样的函数具备不一样的做用域
def f1(): x = 1 def f2(): x = 3 print(x) f1() # 1 x = 1 和 x = 3的两个x毫无关系
全局做用域内的变量和局部做用域内的变量就算变量名相同也毫无关系 ; 不一样函数的局部做用域内的变量就算变量名相同也毫无关系
(全局) x = 1 def f1(): global x x = 3 f1() print(x) # 3
(局部) def f1(): x = 1 def f2(): nonlocal x x = 3 print(x) f1() # 3
lt = [1,2,3] def f1(): lt.append(4) f1() print(lt) # [1,2,3,4]
内置--》全局--》局部
做用域:
内置和全局 --》 全局做用域
局部 --> 局部做用域
x = 1 def func(): x = 3 func() print(x) # 1
def f1(): x = 1 def f2(): x = 3 f2() print(x) f1() # 1
把函数A和变量x 包在一个函数B内部, 而后经过函数B的返回值 把函数A和变量x 共同返回出来
x = 1 def f1(): print(x) x = 2 f1() # 若是不使用闭包,可能出现这种状况,全局变量的变化会影响函数值 # def f2(): # x = 100 # # def f1(): # print(x) # # return f1 # # x = 2 # # f = f2() # f = f1 # 不受外界变量的影响了 # # print(f'f.__closure__[0].cell_contents: {f.__closure__[0].cell_contents}') # 闭包函数f的闭包元素 # f() # f1() def f2(x): def f1(): print(x) return f1 x = 2 f_100 = f2(100) # f = f1 # 不受外界变量的影响了 f_100() # f1() f_100() # f1() f_100() # f1() f_200 = f2(200) f_200() f_200() f_200() f_200()
# 装饰器:装饰的一个函数,写装饰器就是写函数,装饰一个函数 # 1. 被装饰的函数不能改变其调用方式 # 2. 被装饰的函数不能改变其源代码 import time # start = time.time() # index() # end = time.time() # print(end - start) # 装饰器 # def index(): # start = time.time() # index() # end = time.time() # print(end - start) # 完整的两层装饰器, 三层装饰器就是给两层加参数 def sanceng(engine): def outter(func): def wrapper(*args, **kwargs): # 形参 if engine == 'file': start = time.time() res = func(*args, **kwargs) # 原始的index # 实参 end = time.time() print(end - start) return res elif engine == 'db': res = func(*args, **kwargs) return res return wrapper return outter @sanceng('file') def index(x): print(x) print('from index') return 123 # outter = sanceng('db') # outter = outter # index = outter(index) # index = wrapper index(1) # wrapper() def outter(func): def wrapper(*args,**kwargs): res = func(*args,**kwargs) return res return wrapper @outter def index(x): print('from index') def sanceng(engine): def outter(func): def wrapper(*args, **kwargs): res = func(*args, **kwargs) return res return wrapper return outter @sanceng('file') def index(x): print('from index')
可迭代对象: 具备iter方法的对象, 可迭代对象不必定是迭代器对象 迭代器对象: 具备iter和next方法的对象, 迭代器对象必定是可迭代对象,迭代器对象必定是可迭代对象, 迭代器对象加上iter方法仍是迭代器自己 for 循环原理 for i in lt: print(i) 1. 把lt变成迭代器对象 1. 而后迭代使用__next__方法获取每个元素 1. 捕捉异常中断while循环 # 不依赖索引迭代取值
取代了if...else
一行实现列表生成
[i for i in range(10000000)]
一行实现字典生成
{ k:v for k,v in dic.items()}
节省内存空间,生成器不使用next方法不会取值的(一只老母鸡),而列表全取完展示给你(一筐鸡蛋)
(i for i in range(1000000))
带有yield关键字的函数
def func(): yield 1 print(2) yield 3 g = func() # g是生成器, 具备iter和next方法,生成器就是迭代器对象 for i in g: print(i)
yield:
1. 暂停函数,下一次next会运行上一个yield的下面的代码
return:
1. 终止函数
匿名函数,他没有绑定名字,使用一次即被收回,加括号既能够运行。
没有名字的函数, 不单独使用
# f = lambda x:x+1 # f(1)
和max/min/filter/sorted/map联用
递归的核心: 递进的时候可以达到一个结果,问题规模愈来愈小(不必定要真正的达到); 设置一个条件,可以让最后一次函数调用结束;
递归是函数调用函数自己,而后有结束条件
递归代码(递归更多的是一种思想,用来解决某种问题)
count = 1 # 2 # 3 def f1(): global count # 下面的count是全局的count if count > 100: return count += 1 # 2 # 3 print(count) # 2 # 3 f1() f1()
直接调用:直接调用指的是:直接在函数内部调用函数自身。
间接调用:间接调用指的是:不在原函数体内调用函数自身,而是经过其余的方法间接调用函数自身。
递归必需要有两个明确的阶段:
递归的精髓在于经过不断地重复逼近一个最终的结果。
递归的使用方法:
参考二分法:
简单来讲就是在一列数里边一直从中间截断,而后看须要的数字在那边就保留那边知道只剩那个须要的数。
1.bytes()
解码字符。
res = '你好'.encode('utf8') print(res) b'\xe4\xbd\xa0\xe5\xa5\xbd' res = bytes('你好', encoding='utf8') print(res) b'\xe4\xbd\xa0\xe5\xa5\xbd'
2.chr()/ord()
chr()参考ASCII码表将数字转成对应字符;ord()将字符转换成对应的数字。
print(chr(65)) A print(ord('A')) 65
3.divmod()
分栏。
print(divmod(10, 3)) (3, 1)
4.enumerate()
带有索引的迭代。
l = ['a', 'b', 'c'] for i in enumerate(l): print(i) (0, 'a') (1, 'b') (2, 'c')
5.eval()
把字符串翻译成数据类型。
lis = '[1,2,3]' lis_eval = eval(lis) print(lis_eval) [1, 2, 3]
6.hash()
是否可哈希。
print(hash(1)) 1
1.abs()
求绝对值。
print(abs(-13)) # 求绝对值 13
2.all()
可迭代对象内元素全为真,则返回真。
print(all([1, 2, 3, 0])) print(all([])) False True
3.any()
可迭代对象中有一元素为真,则为真。
print(any([1, 2, 3, 0])) print(any([])) True False
4.bin()/oct()/hex()
二进制、八进制、十六进制转换。
print(bin(17)) print(oct(17)) print(hex(17)) 0b10001 0o21 0x11
5.dir()
列举出全部time的功能。
import time print(dir(time)) ['_STRUCT_TM_ITEMS', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'altzone', 'asctime', 'clock', 'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', 'mktime', 'monotonic', 'perf_counter', 'process_time', 'sleep', 'strftime', 'strptime', 'struct_time', 'time', 'timezone', 'tzname', 'tzset']
6.frozenset()
不可变集合。
s = frozenset({1, 2, 3}) print(s) frozenset({1, 2, 3})
7.globals()/loacals()
查看全局名字;查看局部名字。
# print(globals()) def func(): a = 1 # print(globals()) print(locals()) func() {'a': 1}
8.pow()
print(pow(3, 2, 3)) # (3**2)%3 0
9.round()
print(round(3.5)) 4
10.slice()
lis = ['a', 'b', 'c'] s = slice(1, 4, 1) print(lis[s]) # print(lis[1:4:1]) ['b', 'c']
11.sum()
print(sum(range(100))) 4950
12.__import__()
经过字符串导入模块。
m = __import__('time') print(m.time()) 1556607502.334777
面向过程编程是解决问题的一种思想,面向过程编程,核心是编程二字,过程指的是解决问题的步骤,即先干什么、后干什么、再干什么、而后干什么……
能够将面向过程编程想象成工厂流水线,循序渐进的运行。
优势:复杂的问题流程化,进而简单化
缺点:扩展性差。
'''
1.注册 2.登陆 3.查看额度 4.提现 5.还款 6.转帐 7.查看流水 8.购物功能 9.查看购物车 10.注销 q.退出
一个项目是如何从无到有:
1.需求分析:
2.程序的架构设计 用户视图层: 用户与程序交互的. 小的逻辑判断 接口层: 业务逻辑的处理 数据层: 对数据进行存\取 不设计程序架构的问题: 1.逻辑不清晰 2.结构不清晰 3.不便于维护 设计程序的好处: 1.逻辑清晰 2.结构清晰 3.便于维护 4.程序的解耦合 3.分任务开发 项目经理: 把开发任务分发给开发人员: 提升项目开发效率 较少项目开发周期 4.测试: 黑盒测试: 对用户能看到的操做,进行测试. 白盒测试: 对程序的性能进行测试. 5.上线运行 交给运维人员部署上线,运营.