目录
编程语言是人类与计算机交流的介质
编程就是程序员通过某种编程语言所编写的一堆文件
为了让计算机帮助人类工作
编程语言是用来和计算机交互的,但是计算机只认识0和1
直接和硬件交互(用0和1和计算机沟通)
优点:执行效率高
缺点:开发效率低
直接和硬件交互
优点(相较于机器语言):开发效率高
缺点(相较于机器语言):执行效率低
间接和计算机硬件交互
记录下来,全部说完才能翻译.文件编译成另一个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.上线运行
交给运维人员部署上线,运营.
原文:https://www.cnblogs.com/zfb123-/p/11729817.html