python基础篇(完整版)

目录

计算机基础之编程和计算机组成

什么是编程语言

编程语言是人类与计算机交流的介质

什么是编程

编程就是程序员通过某种编程语言所编写的一堆文件

为什么要编程

为了让计算机帮助人类工作

编程语言的分类

编程语言是用来和计算机交互的,但是计算机只认识0和1

机器语言(低级语言)

直接和硬件交互(用0和1和计算机沟通)

优点:执行效率高

缺点:开发效率低

汇编语言

直接和硬件交互

优点(相较于机器语言):开发效率高

缺点(相较于机器语言):执行效率低

高级语言

编译型

间接和计算机硬件交互

记录下来,全部说完才能翻译.文件编译成另一个obj文件.再和计算机沟通得到结果,把代码翻译成机器语言,通过编译器(汇编语言/机器语言写的)

优点(相较于解释型语言):执行效率高

缺点(相较于解释性语言):开发效率低

解释型

说一句翻译一句

优点(相较于编译型语言):开发效率高

缺点(相较于编译型语言):执行效率低

翻译成机器语言,一般是通过解释器(编译型语言写的)

我们写程序一定是程序运行的越快越好,我们应该用编译型

计算机的五大组成

CPU(相当于人类的大脑)

多核CPU(多个大脑,同时(同一时刻)处理多件事情)

控制器

控制硬件

运算器

算术运算和逻辑运算

内存

计算机只认识0和1(高低压电频)

优点:速度快

缺点:断点即消失

外存

优点:容量大,永久保存

缺点:速度慢

固态硬盘

固态硬盘不需要平均延迟时间,RAM(断电即消失) SSD(断电不消失+算法(数学))基于电存储

输入设备

输入信息,(键盘,鼠标等)

输出设备

输出信息, (显示屏,打印机等)

IO设备(输入输出设备)

输入输出信息,(U盘)

应用程序的启动流程

  1. 双击qq(快捷方式-->指向了一个路径(外存)), 其实是去这个位置找到qq内容
  2. CPU再发送指令给内存,让内存读取外存中的qq内容
  3. 运行

32位和64位等区别

32位一次接受32个字节

64位一次接受64个字节

具有向下兼容性(比如说,64位兼容32位,32位不兼容64位)

ROM存储器+CMOS存储器

开机就是告诉计算机操作系统的位置,存储在CMOS存储期内

你重装系统的时候为什么要插U盘: 更改操作系统的路径

硬盘工作原理

机械硬盘上存储的都是0和1

机械手臂: 读取数据

磁道: 存储数据

扇区: 多个磁道组成一块,起始位置

寻找数据的时间:

平均延迟时间: 机械手臂到磁盘的时间 5ms (固态硬盘没有这个时间)

平均寻数据的时间: (0 + 8.3) /2

7200r/min

操作系统

什么是文件

文件是操作系统提供的虚拟单位

什么叫应用程序

应用程序就是一大堆文件

什么是操作系统

操作系统本质还是一个软件

操作系统的作用

操作系统就是把对计算机的复杂指令简单化(对CPU的指令)

操作系统启动

  1. 开机
  2. 启动一个临时操作系统(只做启动操作系统的事情)
  3. 然后临时操作系统会去读取操作系统的路径地址(特殊的CMOS硬件)
  4. 启动真正的操作系统

应用程序和操作系统启动的区别

应用程序依托于操作系统

操作系统依托于临时操作系统

其他的步骤都是一模一样的

网络瓶颈效应

引用木桶效应(可以百度)

因为网络延迟远远大于程序的运行速度,这个时间可以户罗不计。

变量

什么事变量

变量是用来描述世间万物的状态

变量的组成

  1. 变量名:接收变量值
  2. 赋值符号:把变量值赋值给变量名
  3. 变量值:就是一个数值

变量名的命名规范

  1. 变量名由数字/字母/下划线组成,不能以数字开头
  2. 变量名不能以关键字命名
  3. 变量名具有意义

变量名的两种定义方式

height_of_nick = 150, 下划线式

HeightOfNick = 150, 驼峰体

定义变量的三个特征

  1. 打印变量值
  2. 打印变量的内存地址
  3. 打印变量的数据类型

常量

不变的量,常量本质上也是个变量,只不过变量名全大写约定俗成为了常量,以后不要去改变他

python内存管理方式

引用计数

有n个变量名指向一个变量值A,则A的引用计数为n

垃圾回收机制

当变量的引用计数为0的时候,python解释器会自动回收该变量的内存空间

小整数池

[-5, 256]之间,当python解释器打开的时候就已经开辟内存空间存在,不会受垃圾回收机制影响

执行python的两种方式

交互式

优点:运行一句执行语句

缺点:关闭即消失

命令行式

优点: 一直存在

缺点:全部写完才能调试BUG

花式赋值

交叉赋值
x, y = y,x

链式赋值
x=y=z= 10

注释

解释 ; 让代码在python解释器运行的时候不被解释,即让他无意义

单行注释:
  '使用单引号'
多行注释:
'''
可
以
换
行
'''

数据类型基础

数据类型: 不同种类的变量值用不同的数据类型描述

数字类型

整形(int)

  1. 定义方式: age = 18;age = int(18);int('18')
age = 18;age1 = 19  # 不建议使用
print(age,age1)

age,age1 = 18,19  # 解压缩
  1. 作用: 描述年龄/id号等
  2. 使用方式:+-*/ % // **( a = 1
    b = 2
    print(a+b)
    print(b-a)
    print(a*b)
    print(a/b)
    print(a//b) # 取整
    print(a%b) # 取余
    print(a**b) # 幂)
  3. 如果使用log方法,导入import cmath

作用

年龄/身份证号码/身高/体重等

浮点型(float)

  1. 定义方式:salary=3.2;salary=float(3.2);float('3.2')
  2. 作用:描述薪资等
  3. 使用方法:+-*/ % // **( a = 1
    b = 2
    print(a+b)
    print(b-a)
    print(a*b)
    print(a/b)
    print(a//b) # 取整
    print(a%b) # 取余
    print(a**b) # 幂)
  4. 如果使用log方法,导入import cmath

作用:

可以用来表示薪水等

字符串类型

  1. 定义方式:
name = 'nick';name = "nick"
name = str('nick')
name = '''
nick
nick
'''
name = """
nick
nick
"""


x = str(10) # '10'
  1. 作用: 名字等
  2. 使用方法
s1 = 'nick'
s2 = 'handsome'

s1 + s2

s3 = 10  # nickhandsome
s1 + str(10)  # nick10
# int(s1) + s3


s1 * 5  # 'nicknicknicknicknick'

列表

  1. 定义方式: []内用逗号隔开多个元素(所有数据类型)

ctrl+鼠标左键 进入源码模式

  1. 作用: 存储多个值
  2. 使用方法
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]

字典

  1. 定义方式: {}内以逗号隔开键值对 key(一般为字符串,具有描述意义):value(为任意数据类型) # 哈希表
  2. 作用: 存储多个值,不依赖索引取值,而通过key取值
  3. 使用方法
nick_info_dict = {'name':'nick','height':180}

nick_info_dict['height']

布尔类型

  1. True和False,一般只在条件判断的时候

除了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)
'''

python2中的与用户交互

raw_input()  # 与用户交互和python3中的input一模一样



input()  # 与用户交互,必须得指定输入的类型,输入什么类型拿到什么类型

三种格式化输出

占位符

  1. %s 匹配所有数据类型的字符
  2. %d 只匹配数字

format格式化

name = 'nick'

print('name:{}'.format(name))

f-string格式化

name = 'nick'

print(f'name:{name}')


# :.2f 保留两位小数

基本运算符

算术运算符

+-*/ % // **

逻辑运算符

  1. and: 两个条件都为真,即为真,否则都为假
  2. or:两个条件其中一个为真,则为真,否则都为假
  3. not: 真变假,假变真

赋值运算符

= += -= *= /= %= //= **=

比较运算符

> >= < <= == !=

身份运算符

  1. is: 比较两个变量的id
  2. is not: 比较两个变量的id(A is not B == not A is B)

运算符的优先级(了解)

  1. 如果你要优先运算,加括号

流程控制之if判断

单分支结构

'''
if <条件>:
	<代码块>
'''

伪代码: 大概知道代码的意思,但是这种代码无法运行

双分支结构

'''
if <条件>:
	<代码块1>
else:
	<代码块2>
'''

多分支结构

'''
if <条件1>:
	<代码块1>
elif <条件2>:
	<代码块2>
...
else:
	<代码块3>
'''

if判断的嵌套

'''
if <条件1>:
	if <条件2>:
		<代码块>
'''
if 条件:
    # TODO
    pass

while循环

不可控, 循环一切

while + break

跳出本层循环,跳出循环

while + continue

跳出本次循环

while + else

循环没有被break终止才会执行

for循环

可控, 循环容器类型元素 + 字符串(可迭代数据类型)

for + break

for + continue

for + else

进制转换

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

数值类型内置方法

整型

  1. 作用:描述年龄,id
  2. 定义方式: x = 10, x = int('10')
  3. 使用方法: 算术运算 和 比较比较运算
  4. 有序无序: 压根没有这一说
  5. 存一个值还是多个值:一个值
  6. 可变还是不可变: 不可变

浮点型

  1. 作用:描述薪资
  2. 定义方式: x = 10.1, x = float('10.1')
  3. 使用方法: 算术运算 和 比较比较运算
  4. 有序无序: 压根没有这一说
  5. 存一个值还是多个值:一个值
  6. 可变还是不可变: 不可变

字符串类型内置方法

  1. 作用: 描述姓名,性别
  2. 定义方法
name = 'nick'

# 
 换行
# 	 缩进,4个空格
# 
+end='' 覆盖上一次打印

name = r'
	a'   # 取消
和	的作用
name = '\n\ta'  # 取消
和	的作用
  1. 内置方法
    1. 优先掌握
      1. 索引取值
      2. 切片
      3. strip
      4. split
      5. len长度
      6. 成员运算
      7. for 循环
    2. 需要掌握
      1. upper/lower
      2. startswith/endswith
      3. rstrip/lstrip
      4. rsplit
      5. isdigit/isalpha
      6. join
      7. replace
    3. 了解
      1. find/rfind/index/rindex/count
      2. capitalize/swapcase/title
      3. center/ljust/rjust/zfill
      4. is系列(真正的了解)
    4. 存一个值还是多个值:一个值
    5. 有序or无序:有序
    6. 可变还是不可变:不可变

有序or无序

有索引的就是有序,无索引的就是无序

可变or不可变

值变id不变的是可变类型;值变id变的是不可变

列表list

  1. 定义方式: []内逗号隔开多个元素(任意数据类型)
  2. 使用方法
    1. 优先掌握
      1. 索引取值,索引修改值
      2. 切片
      3. 成员运算
      4. 长度
      5. for循环
      6. append
      7. del删除
    2. 需要掌握
      1. insert
      2. pop
      3. remove
      4. count
      5. find
      6. index
      7. extend
      8. sort
      9. reverse
      10. clear
      11. copy
      12. ...

字典dict

  1. 定义方式: {}内以逗号隔开键值对,key(具有描述意义,不能为可变数据类型):value(具体的任意数据类型)
  2. 使用方法
    1. 优先掌握
      1. 按key取值,按key修改值,按key增加值
      2. 成员运算
      3. 长度
      4. for循环
      5. keys/values/items
      6. del 删除
      7. get
    2. 需要掌握
      1. copy
      2. update
      3. clear
      4. setdefault
      5. fromkeys
      6. pop(按key删除)
      7. popitem(随机删除,但是删除最后一个)

元组tuple

  1. 定义方式: ()内以逗号隔开多个任意数据类型的元素
  2. 不可更改的列表,创建后就只能是那样了

集合set

1. 定义方式: {}内以逗号隔开多个元素(不能为可变数据类型)
  1. 使用方法:

布尔类型bool

  1. True
  2. False

条件判断后触发,一般不单独使用

一、Python基础实战之猜年龄游戏

  1. 给定年龄,用户可以猜三次年龄
  2. 年龄猜对,让用户选择两次奖励
  3. 用户选择两次奖励后可以退出
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 错误类型()  # 抛出异常

数据类型分类

可变or不可变

可变 不可变
列表/字典/集合 整型/浮点型/字符串/元组

有序or无序

有序 无序
字符串/列表/元组 字典/集合

一个值or多个值

一个值 多个值
整型/浮点型/字符串 列表/元组/字典/集合

文件的基本操作

打开文件的流程

# 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和3字符编码的区别

  1. 打开python解释器
  2. python解释器相当于文本编辑器,读取二进制转化为普通字符 a = 1
  3. 对转化后的普通字符进行解释(定义变量就要新开辟内存空间存放变量)
代码详情 Python2执行情况 Python3执行情况
coding:gbk
print('中')
终端:utf8
乱码 不乱码
coding:utf8
print('中')
终端:utf8
不乱码 不乱码
coding:gbk
print(u'中')
终端:utf8
不乱码 不乱码
coding:utf8
print(u'中')
终端:utf8
不乱码 不乱码

python2

用文件指定的编码方式存储定义后的变量

如果文件指定编码为'gbk' ,那就会以gbk的形式存储变量, 本来打印的是0和1,但是终端会自动对你的0和1安装终端默认的编码转换成字符 ,如果终端的默认编码是utf8 ,乱码; 如果终端默认编码是gbk,不乱吗

如果定义变量前加上u,coding:xxx不会对他造成任何影响, 因为会用unicode编码存储变量, 终端是任何类型的编码都可以识别

python3

用unicode编码方式存储定义后的变量

以后写文件以什么格式存储,就以什么格式读取

文件的三种打开方式

r : 只读

f.read()

w: 清空后写入(文件不存在自动创建)

f.write()

a: 追加(文件不存在自动创建)

f.write()

文本模式:t

二进制模式:b

t/b无法单独使用,只能和r/w/a一起使用

with管理文件上下文

with open() as f: # 自动关闭

pyinstaller的使用

pip instlal pyinstaller

切换路径到文件夹(文件夹包含img.ico和test.py这两个文件)

pyinstaller -i img.ico -F test.py

文件的高级应用

文件的高级打开模式(不推荐使用)

  1. r+
  2. a+
  3. w+

文件指针的移动方法(不推荐使用)

  1. seek字节
    1. 0文件头
    2. 1当前位置
    3. 2文件末
  2. tell字节
  3. read(n)字符
  4. truncate(n)字节, 截断文本
    1. truncate(0) 清空文件

文件的修改

方式一

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

函数对象

  1. 引用
  2. 作为函数的参数
  3. 作为函数的返回值
  4. 作为容器元素

函数的嵌套

函数内套函数

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毫无关系

总结

全局作用域内的变量和局部作用域内的变量就算变量名相同也毫无关系 ; 不同函数的局部作用域内的变量就算变量名相同也毫无关系

global

(全局)
x = 1

def f1():
    global x
    x = 3
  
f1()
print(x)  # 3

nonlocal

(局部)
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]

名称空间与作用域

内置--》全局--》局部

作用域:

内置和全局 --》 全局作用域

局部 --> 局部作用域

  1. 全局作用域的(x=1)和局部作用域的(x=3)没有关系
x = 1

def func():
    x = 3
func()

print(x)  # 1
  1. 局部作用域1(x=1) 和 局部作用域2 中的(x=3)没有关系
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的下面的代码
  1. 返回值(只能next获取)
  2. 有几个yield就只能用几次next

return:

1.  终止函数
  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. 递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小
  2. 回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯。

递归的精髓在于通过不断地重复逼近一个最终的结果。

递归的使用方法:

参考二分法:

简单来说就是在一列数里边一直从中间截断,然后看需要的数字在那边就保留那边知道只剩那个需要的数。

内置函数

1.1 掌握

  1. bytes
  2. chr/ord
  3. divmod
  4. enumerate
  5. eval
  6. hash

1.bytes()

解码字符。

res = '你好'.encode('utf8')
print(res)
b'xe4xbdxa0xe5xa5xbd'
res = bytes('你好', encoding='utf8')
print(res)
b'xe4xbdxa0xe5xa5xbd'

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.2 了解

  1. abs
  2. all
  3. any
  4. bin/oct/hex
  5. dir
  6. frozenset
  7. gloabals/locals
  8. pow
  9. round
  10. slice
  11. sum
  12. import

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

面向过程编程

面向过程编程是解决问题的一种思想,面向过程编程,核心是编程二字,过程指的是解决问题的步骤,即先干什么、后干什么、再干什么、然后干什么……

可以将面向过程编程想象成工厂流水线,按部就班的运行。

优点:复杂的问题流程化,进而简单化

缺点:扩展性差。

ATM+购物车

项目需求如下:

'''

  • 额度15000或自定义 ---> 注册
  • 实现购物商城,买东西加 购物车,调用信用卡接口结账 ---> 购物车功能,支付功能
  • 可以提现,手续费5% ---> 提现
  • 支持多账户登录 ---> 登录
  • 支持账户间转账 ---> 转账
  • 记录日常消费流水 ---> 记录流水
  • 提供还款接口 ---> 还款
  • ATM记录操作日志 ---> 记录日志
  • 提供管理接口,包括添加账户、用户额度,冻结账户等... ---> 管理员功能
  • 用户认证功能 ---> 登录认证装饰器
    '''

用户界面功能

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