• 文件操作

  • 文件的读写模式

  • 文件的操作模式

  • 文件相关操作

  • 文件内光标移动

  • 文件内容修改

  • 函数前戏

  • 函数的语法结构

  • 函数的定义和调用

  • 函数的分类

  • 函数的返回值

  • 函数的参数

  • 函数参数之位置参数

  • 默认参数

  • 可变长形参

  • 可变长实参

  • 名称空间

  • 名称空间存活周期及作用范围(域)

  • 名字查找顺序

  • 查找顺序案例

  • global与nonlocal关键字

  • 函数名的多种用法

  • 闭包函数

  • 装饰器简介

  • 装饰器模板

  • 装饰器语法糖

  • 多层语法糖

  • 有参装饰器

  • 装饰器修复技术

  • 递归函数

  • 算法简介及二分法

  • 三元表达式

  • 各种生成式/表达式/推导式

  • 匿名函数

  • 常见的内置函数

  • 重要内设置函数

  • 常见的内置函数

  • 可迭代对象

  • 迭代器对象

  • for循环本质

  • 异常捕获/处理

  • 周测

1.文件操作

1.文件的概念
	就是操作系统暴露给用户操作硬盘的快捷方式,双击一个文件就是将硬盘中的数据加载到内存,保存文件就是将内存中的数据刷到硬盘
    
2.代码打开文件的两种方式:
    方式1: 不推荐,因为close关键字经常被忘记
        f = open(文件路径,读写模式, encoding= 'utf8')
        f.close()  # 保存文件
    方式2:
    	  with open(r'a.txt', 'r', encoding='utf8')as f1:
            with子代码块
     方式2好处在于子代码运行结束后自动调用close方法关闭资源
    
"""
注意:
1.open方法第一个参数是文件路径,并且\跟一些字母组合产生特殊含义导致文件路径查找混乱,为了解决混乱可以在字符串前面加上r。
	D:\a\n\t
	r'D:\a\n\t'
	
2.with支持一次性打开多个文件:
	with open() as f1, open() as f2:
		子代码
"""

2.文件的读写模式

1.r:只读模式:只能读不能写
	1.1:文件路径不存在:会直接报错
   with open (r'a.txt', 'r', encoding='utf8') as f1:
    	print(f1.read())
	1.2文件路径存在:正常读取文件内容
   with open(r'a','r', encoding='utf8') as f1:
    print(f1.read())
    
2.w:只写模式:只能写不能看
	2.1文件路径不存在:自动创建
   with open(r'b.txt', 'w', encoding='utf8') as f2:
    f2.write('十一过得快吗\n真快')  
    
	2.2文件路径存在:先清空文件内容,之后再写入
	with open(r'b.txt', 'w', encoding='utf8') as f2:
    f2.write('假期综合征\n需要尽快调整')
"""
换行符需要自己添加,并且作业中数据对比中要注意该问题存在,需要用strip关键字去掉首尾换行符之后做对比
"""

3.a:只追加模式:文件末尾添加数据
	3.1文件路径不存在:自动创建(同w模式)
	with open (r'c.txt', 'a', encoding='utf8') as f3:
    f3.write('a模式文件路径不存在会发生什么呢')
    
	3.2文件路径存在:自动在末尾等待追加内容
"""
关键字:pass
补全语法功能本身并无任何含义,适用于功能搭建阶段
"""

3.文件的操作模式

1.文本模式(t模式):
    默认的模式,我们上面写的r,w,a,都是rt,wt,at的简写。
    2.只能操作文本文件
    3.需要制定encoding参数,如果不知道则会采用计算机默认的编码
    
2.二进制模式(b模式或bytes模式)
	不是默认的模式,rb,wb,ab不能简写
    1.可以操作任意类型文件
    2.读写都是以bytes为单位
    3.不需要指定encoding参数,因为它已经是二进制模式了,不需要编码
    
"""
二进制模式和文本模式针对文件路径是否存在的情况规律是一样的
"""

4.文件的相关操作

1.read():一次性读取文件内容,并且目标停留在文件末尾,继续读取则没有内容。并且当文件内容比较多时,该方法可能会造成计算机内存溢出,括号内还可以写数字,在文本模式下表示读取几个字符。
with open (r'c.txt', 'r',encoding='utf8') as f:
    print(f.read())
    print(f.read())
    print(f.read())  # r模式下执行打印三遍read()到底会执行几次呢
"""
三个print最终只执行了一次,因为一次性读取文件内容,鼠标停留在了文档末尾。
"""

2.for循环:
    一次性只读一行内容,避免因为文件内存过大导致内存溢出
with open (r'b.txt', 'r',encoding='utf8') as f:
    for line in f:
        print(line)
"""
为什么原文件每行没有间隙,pycharm打印出来就有???
	因为for循环之后line中包含了一个换行符(\n),而print()关键字本身也自带换行符,相当于每循环打印一行会有两个换行符。
"""

3.readline():一次只读一行内容,要想打印多行需要多个print()
    
4.readlines():一次性读取文件内容,会把每行内容当做元素组成一个列表,列表中的内容会自带换行符。
    
5.readable:判断文件是否具备读数据的能力
    
6.write():写入数据
    
7.writable():判断文件是否具备写数据的能力
    
8.writelines():接受一个列表,一次性将列表中所有的数据写入
    
9.flush():将内存文件中数据立刻刷到硬盘,等价于ctrl + s

5.文件内光标移动

监测文档是否变化练习题:
import time

with open(r'a.txt', 'rb') as f:
    f.seek(0, 2)
    while True:
        line = f.readline()
        if len(line) == 0:
            # 没有内容
            time.sleep(0.5)
        else:
            print(line.decode('utf8'), end='')

6.文件内容修改

方式1:覆盖写:直接在文件中的某个部分讲新的内容覆盖掉原内容
	关键字:replace(),里面的两个参数分别表示替换前的内容和想要替换的内容。
with open(r'a.txt', 'r', encoding='utf8') as f1:
    data = f1.read()
with open(r'a.txt', 'w', encoding='utf8') as f2:
    f2.write(data.replace('danny', 'jenny'))
    
方式2:换地方写:先在另外一个地方写入内容,然后将源文件删除,将新文件命名成源文件
import os

with open('a.txt', 'r', encoding='utf8') as read_f, \
        open('.a.txt.swap', 'w', encoding='utf-8') as write_f:
    for line in read_f:
        write_f.write(line.replace('tony', 'kevinSB'))
        
        
os.remove('a.txt')  # 删除a.txt
os.rename('.a.txt.swap', 'a.txt')  # 重命名文件

7.函数前戏

name_list = ['jason', 'kevin', 'oscar', 'jerry']
需求1.想要统计列表中的元素个数,该怎样做?
name_list = ['jason', 'kevin', 'oscar', 'jerry']
print(len(name_list))  # 4

需求2:如果不能用len(),请统计列表中元素个数:
count = 0
for i in name_list:
    count += 1
print(count)  # 4

统计列表内部数据值个数的代码需要在很多地方使用,因此引出函数概念:
"""
循环:相同代码在相同位置反复执行。
函数:相同代码在不同位置反复执行。
ps:相同的代码不是真正一模一样而是可以通过传入的数据值不同而做出不同的改变。
"""
定义一个简单的函数,统计列表中的个数,并且在其他需要的地方可以调用到该数据值:
name_list = ['jason', 'kevin', 'oscar', 'jerry']
def my_len():
	count = 0
	for i in name_list:
		count += 1
	print(count)
my_len()  # 4
"""
函数相当于是工具(具有一定功能)
    不用函数
        修理工需要修理器件要用锤子 原地打造 每次用完就扔掉 下次用继续原地打造
    用函数
        修理工提前准备好工具 什么时候想用就直接拿出来使用
"""    

8.函数的语法结构

def 函数名(参数):
    '''函数注释'''
    函数体代码
    return 返回值
1.def
	定义函数的关键字
2.函数名
	命名等同于变量名
3.参数
	可有可无,主要是在使用函数的时候规定要不要传外界数据进来
4.函数注释
	类似于工具说明书
5.函数体代码:
    是整个函数的核心,主要取决于程序员的编写
6.return
	使用函数之后可以返回给使用者的数据,可有可无

9.函数的定义和调用

1.函数在定义阶段只检测语法,不执行代码,如果函数体代码有错误不调用也不会报错。
def index():
    pass

2.函数在调用阶段才会执行函数体代码
index()

3.函数必须先定义后调用

4.函数定义阶段使用关键字def,函数调用阶段使用函数名加括号(在赋值符号右边也可以)

10.函数的分类

1.空函数
	函数体代码为空,使用pass或者...补全(一般推荐使用pass),空函数主要用于前期的功能框架搭建
def register():
    """注册功能"""
    pass

2.无参函数
	定义函数的时候括号内没有参数
	def index():
        print('from index function')
        
3.有参函数
	定义函数的时候括号内写参数,调用函数的时候括号内传参数
def func(a):
    print(a)

11.函数的返回值

1.函数的返回值:调用函数之后返回给调用者的结果
    
2.如何获取返回值:变量名,赋值符号,函数的调用
def func():
    print('func')
res = func() 
先执行func函数,然后把返回值赋值给变量res

3.函数返回值的多种情况
	3.1函数体代码中没有return关键字,默认返回None
def index():
    print('from index')
res = index()  # from index
print(res)  # None

	3.2函数体代码有return,如果后面没有写任何东西还是返回None
def index():
    print('from index')
    return
res = index()  # from index
print(res)  # None

	3.3函数体代码有return,后面有什么就返回什么
def index():
    print('from index')
    return 'index'
res = index()  # from index
print(res)  # index

	3.4函数体代码有return并且后面有多个数据值,则自动组成元组返回
def func():
    print('from index')
    return 123, 'jason', 1.11
res = func()  # from index
print(res)  # (123, 'jason', 1.11)

	3.5函数体代码遇到return会立刻结束
def func():
    print('from index')
    return 123, 'jason', 1.11
    print('我会不会被执行')  # 因为在return后面所以不会执行
res = func()  # from index
print(res)  # (123, 'jason', 1.11)

12.函数的参数

1.形式参数:在函数定义阶段括号内填写的参数,简称'形参'
   
2.实际参数:在函数调用阶段括号内填写的参数,简称'实参'
    
"""
形参与实参的关系:
	形参类似于变量名,在函数定义阶段写,最好见名知意
	def register(name, pwd):
		pass
		
	实参类似于数据值,在函数调用阶段与实参临时绑定,函数运行结束立刻断开
	register('jason', 123),表示形参name与jason临时绑定,形参pwd与123临时绑定
"""

13.函数参数之位置参数、关键字参数

"""
当子代码只有一行并且很简单的情况下,可以直接写在冒号的后面,不用换行
"""
位置形参
	函数定义阶段括号内从左往右依次填写的变量名
    def func(a, b, c):pass

位置实参
	函数调用阶段括号内从左往右依次填写的数据值
    func(2, 3, 4)
"""
位置参数应按照位置及数量一一对应地传值,实参多一个不行,少一个也不行
"""
关键字参数
	指名道姓地传参
def index(a, b):
    print(a, b)
index(b=1, a=2)  # 2 1    
"""
关键字参数一定要在位置参数的后面,同一个形参不能被多次赋值
"""
def index(a, b):
    print(a, b)
index(1, b=2)  # 1 2

实参可以传数据值,也可以传绑定了数据值的关键字
def index(a, b,):
    print(a, b)
c = 1
d = 2
index(c, d)  # 1 2
"""
越短的越简单的越靠前
越长的越复杂的越靠后
但是遇到下列的情况除外
    同一个形参在调用的时候不能多次赋值
"""

14.默认参数

本质就是关键字参数,提前就已经给了,用户可以不传,也可以传
"""
默认参数的定义也遵循段的简单的靠前,长的复杂的靠后
"""
def index(name, age, job,gender='male'):
    print(f"""
    姓名:{name}
    性别:{gender}
    年龄:{age}
    职业:{job}
    """)
index('jason', 18, 'teacher')
index('max', 22, 'programmer', 'female')


15.可变长形参

1.*在形参中,用于接收多余的位置参数,组成元组赋值给*后面的变量名
def index(a, *b):
    print(a, b)
index(1, 2)  # 1 (2,)
index(1, 2, 3, 4)  # 1 (2, 3, 4)

def index(a, *b):
    print(a, b)
index(1)  # 1 ()  # 没有多余的则会直接返回一个空元组

2.**在形参中,用于接收多余的关键字参数,组成字典赋值给**后面的变量名
def index(a, **b):
    print(a, b)
index(a=1, b=2, c=3)  # 1 {'b': 2, 'c': 3}
index(b=1, a=2, c=3)  # 2 {'b': 1, 'c': 3} 关键字参数可以不根据位置顺序来传参

def index(a, **b):
    print(a, b)
index(a=1)  # 1 {} 没有多余的则会返回一个空字典

"""
在形参中*和**必须都在形参中的最后一个元素,遵循短的、简单的在前,长的、复杂的在后
"""

3.*和**可以混合使用,由于使用频率很高,后面跟的变量名推荐使用*args,**kwargs
def index(*args, **kwargs):
    print(args, kwargs)
index()  # () {}
index(1, 2, 3, 4)  # (1, 2, 3, 4) {}
index(a=1, b=2, c=3)  # () {'a': 1, 'b': 2, 'c': 3}
index(1, 2, a=2, b=1)  # (1, 2) {'a': 2, 'b': 1}

def index(n, *args, **kwargs):
    print(n, args, kwargs)
index(a=1, 1, 2, 3, b=2)  # 报错,因为n首先要接受一个位置参数
index(1, 2, 3, a=1, b=2)  # 1 (2, 3) {'a': 1, 'b': 2}

16.可变长实参

在实参中*类似于for循环,将所有循环遍历出来的数据按照位置参数一次性传给函数
l1 = [1, 2, 3]
t1 = (1, 2, 3)
s = 'max'
set = {1, 3, 2}
d = {'user_name': 'max', 'age': 25, 'gender': 'male'}
def index(a, b, c):
    print(a, b, c)
index(*l1)  # 1 2 3
index(*t1)  # 1 2 3
index(*s)  # m a x
index(*set)  # 1 2 3  # 集合时无序的
index(*d)  # user_name age gender  # 字典只会遍历键

**在实参中将字典打散成关键字参数,并且传递给函数
d = {'user_name': 'max', 'user_age': 18, 'job': 'programmer'}
def index(user_name, user_age, job):
    print(user_name, user_age, job)
index(**d)  # max 18 programmer

17.名称空间

名称空间就是用来存储变量名与数据值绑定关系的地方(也可以简单地理解为存储变量名的地方)

1.内置名称空间:解释器运行自动产生,里面包含了很多内置的名字,例如len,print,input
    
2.全局名称空间:py文件运行产生,里面存放文件级别的名字(除了内置的名字和函数体代码里的变量名,其他的变量名都储存在全局名称空间中,最外层函数的函数名也是储存在全局名称空间中)
name = 'jason' 
age = 18
while True:
    gender = 'male'
    
3.局部名称空间:
    函数体代码运行\类体代码运行产生的空间

18.名称空间存活周期及作用范围(域)

1.存活周期:
    内置名称空间:解释器启动创建,关闭则销毁
    全局名称空间:py文件运行则创建,运行结束则销毁
    局部名称空间:函数体代码运行创建,函数体代码结束则销毁
        
2.作用域:
    内置名称空间:解释器级别全局有效
    全局名称空间:py文件级别全局有效
    局部名称空间:函数体代码内有效

19.名字的查找顺序

涉及到名字的查找,一定要首先搞明白自己在哪个空间
如果我们在局部名称空间,查找顺序为:局怒名称空间>全局名称空间>内置名称空间
如果我们在全局名称空间,查找顺序为:全局名称空间>内置名称空间
    
ps:名字查找顺序可以打破

20.查找顺序案例

1.相互独立的局部名称空间默认不能相互访问
def index():
    name = 'jason'
    print(age)

def func():
    age = 18
    print(name)

index()
func() # 报错,不同局部名称空间之间默认不能互相访问

2.局部名称空间嵌套
	先从自己的局部名称空间找,然后再从外层局部名称空间找,找不到在按照顺序找全局名称空间、内置名称空间。
x = '干饭了'
    def func1():
        x = 1
        def func2():
            x = 2
            def func3():
                print(x)
                x = 3
            func3()
        func2()

    func1()  # 报错,因为在func3()的局部名称空间下先打印x,再定义x=3,这样操作不允许,要么删掉x=3,要么把x=3放在print(x)之前
    
x = '干饭了'
def func1():
    x = 1
    def func2():
        x = 2
        def func3():
            x = 3
            print(x)
        func3()
        print(x)
    func2()
    print(x)
func1()  # x不一样是因为每个局部名称空间都有一个不同的x,func3()中的x=3只能定义func3()局部名称空间中的x。  

21.global与nonlocal关键字

1.global:局部名称空间修改全局名称空间中的变量名
money = 100
def index():
    global money
    money = 666
index()
print(money)  # 666

2.nonlocal:内层局部名称空间修改外层局部名称空间中的数据
def outer():
    name = 'jason'
    def inner():
        nonlocal name
        name = 'max'
    inner()
    print(name)
outer()  # max

22.函数名的多种用法

函数名其实绑定的也是一块内存地址,只不过该地址里面存放的不是数据值而是一段代码,函数名加括号就会找到该代码并执行
1.可以当做变量名赋值
def index():
    print('from index')
res = index
res()  # from index

2.可以当做函数的参数
"""
print(函数名(不加括号))会显示函数的内存地址
"""
def index():
    print('from index')

def func(a):
    print(a)
    a()
func(index)  # <function index at 0x0000016F90827B80> from index

3.可以当做函数的返回值
def index():
    print('from index')

def func():
    print('from func')
    return index
res = func()  # from func,调用func()函数,把index返回给res,res = index
print(res)  # <function index at 0x00000205479B7B80> 打印index函数的内存地址
res()  # from index 调用index()函数

4.可以当做容器,内部可以存放多个数据
def register():
    print('注册功能')

def login():
    print('登录功能')

def withdraw():
    print('提现功能')

def transfer():
    print('转账功能')

def shopping():
    print('购物功能')

func_dict = {
        '1': register,
        '2': login,
        '3': withdraw,
        '4': transfer,
        '5': shopping
    }
print("""
        1: 注册功能,
        2: 登录功能,
        3: 提现功能,
        4: 转账功能,
        5: 购物功能
""")
choice = input('请输入您的选项>>>:').strip()
if choice in func_dict:
    func_dict.get(choice)()
else:
    print('您输入的任务编号不存在')

23.闭包函数

定义在函数内部的函数,并且使用到了外部函数名称空间中的名字,是另一种给函数传参的方式
"""
1.定义在函数内部的函数
2.内层函数用到外层函数名称空间的名字
"""
传参方式1:用实参直接传参
def index(name, age):
    print(f'{name}先生的年龄是{age}')
index('jason', 18)  # jason先生的年龄是18

传参方式2:闭包函数
def index():
    name = 'jason'
    def func():
        print(name)
    func()
index()  # jason

24.装饰器简介

1.概念:在不改变被封装对象原代码和调用方式的情况下给被装饰对象添加新的功能
    
2.本质:并不是一门新的技术 而是由函数参数、名称空间、函数名多种用法、闭包函数组合到一起的结果
    
3.口诀:对修改封闭 对扩展开放
    
4.事件相关操作
import time  # 引入时间模块
print(time.time())  # 打印当前时间据1970年1月1日00:00所经历的时间
time.sleep(3)  # 时间停滞3秒

import time
start_time = time.time()
print(1 and 0)  # 0
time.sleep(3)
end_time = time.time()
print(end_time - start_time)  # 3.010030746459961

25.装饰器模板

def outer(func):
    def inner(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return inner

26.装饰器语法糖

语法糖会自动将下面紧挨着的函数名当做第一个参数自动传给@函数调用,@后跟最外层函数名
def outer(func):
    def inner(*args, **kwargs):
        res = func(*args, **kwargs)  # 此时的func才是真正的index函数名
        return res
    return inner

@outer  # 等价于index = outer(index)
def index():
    print(from index)
index()  # index()函数名是为了调用inner()函数

@outer
def func1():  # 等价于func1 = outer(func1)
    print('from func1')
func1()

27.多层语法糖

以例题分析:
def outter1(func1):  # 1.定义了outter1()函数
    print('加载了outter1')  # 11.调用outter1()函数,打印
    def wrapper1(*args, **kwargs):   # 12.定义wrapper1()函数
        print('执行了wrapper1')  # 15.执行wrapper1函数,打印
        res1 = func1(*args, **kwargs)  # 16.此时func1 = wrapper2,相当于调用wrapper2函数
        return res1
    return wrapper1  # 14.返回wrapper1给index(),此时wrapper1 = index,相当于调用wrapper1函数

def outter2(func2):  # 2.定义了outter2()函数
    print('加载了outter2')  # 8.打印
    def wrapper2(*args, **kwargs):  # 9.定义wrapper2函数
        print('执行了wrapper2')  # 17.打印
        res2 = func2(*args, **kwargs)  # 18.此时func2 = wrapper3,相当于调用wrapper3()函数
        return res2
    return wrapper2  # 10.返回wrapper2函数给outter1()函数,调用outter1()函数

def outter3(func3):  # 3.定义了outter2()函数
    print('加载了outter3')  # 5.打印
    def wrapper3(*args, **kwargs):  # 6.定义wrapper3函数
        print('执行了wrapper3')  # 19. 打印
        res3 = func3(*args, **kwargs)  # 20.此时func3 = index,相当于调用index()函数
        return res3
    return wrapper3  # 7.返回wrapper3函数名给outter2()函数,继续调用outter2()函数


@outter1  
@outter2
@outter3  # 4.index = outter3(index),首先调用outter3()函数
def index():
    print('from index')
index()

"""
加载了outter3
加载了outter2
加载了outter1
执行了wrapper1
执行了wrapper2
执行了wrapper3
from index
"""

"""
1.多层语法糖得执行顺序是从下往上,最下面一层语法糖调用指定的函数名,并把返回值返回给上一层语法糖,当做上一层语法糖的形参,如果上面没有语法糖了,则把返回值返回给index()
"""

28.有参装饰器

有参装饰器的目的是为了额外给函数传递一个参数,用法是在装饰器的最外层再增加一层闭包函数。
def login_auth(mode):  # 1.定义函数login_auth(),需要一个参数mode
    def outer(func):  # 3.定义outer()函数
        def inner(*args, **kwargs):  # 6.定义inner()函数
            if mode == '1':  # 9.mode = '1',执行子代码
                print('注册功能')  # 10.打印
                res = func(*args, **kwargs)  # 11.此时func才是真正的register,加括号会调用register()函数
                return res
            elif mode == '2':
                print('登录功能')
                res = func(*args, **kwargs)
                return res
        return inner  # 7.返回一个函数名inner
    return outer  # 4.返回函数名outer

@login_auth('1')  # 2.register = login_auth('1'),调用最外层函数,此时mode == '1'
# 5.此时语法糖会变成@outer,等价于register = outer(register),调用outer()函数,此时func = register
def register():
    print('注册成功')  # 12.打印'注册成功'
register()  # 8.将函数名inner返回给register,此时register=inner,调用inner()函数

# @login_auth('2')
# def login():
#     print('登陆成功')
# login()
"""
1.函数名加括号执行最高优先级,优先把括号内的参数传入有参装饰其中
2.最外层函数走完之后里面就是一个普通的装饰器,此时语法糖的函数名也会变成中间层函数的函数名,参数是下面一行的函数名
"""

29.装饰器模板

1.无参装饰器模板(常见),根据要求添执行条件
def outer(func):
    def inner(*args, **kwargs):
        res = func()
        return res
    return inner

@outer()
def index():
	pass

2.有参装饰器模板(不常见)
def login_auth(mode):
    def outer(func):
        def inner(*args, **kwargs)
            res = func()
            return res
        return inner
    return outer

@login_auth('参数')
def index():
    pass

30.装饰器修复技术

是一个锦上添花的操作,仅仅是为了让装饰器效果更加逼真
1.原来的装饰器:index函数的内存地址是inner指向的内存地址,并不是指向原本的index函数的内存地址
def outer(func):
    def inner(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return inner

@outer
def index():
    print('from index')
index()  # from index
print(index)  # <function outer.<locals>.inner at 0x000001CC94CB6280>

2.修复后的装饰器:index函数名的内存地址就是index函数本身的内存地址,可以做到真正意义上的装饰而无破绽
关键字:
from functools import wraps
	@wraps(外层函数的形参)

案例:
from functools import wraps
def outer(func):
    @wraps(func)
    def inner(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return inner

@outer
def index():
    print('from index')
index()  # from index
print(index)  # <function index at 0x000001FFFCCD3430>

31.递归函数

1.函数的调用:函数直接或者间接地调用自身
count = 0
def index():
    global count
    count += 1
    print(count)
    index()
index()
"""
上述代码是用来检测数字自增的极限,也叫最大递归深度,是python解释器田间的安全措施,官网提供的最大递归深度为1000 我们在测试的时候可能会出现996 997 998
"""
2.递归函数:
    1.直接或间接的调用自己
    2.每次调用都比上一次简单,并且要有一个明确的结束条件
    def get_age(n):
        if n == 1:
            return 18
        return get_age(n-1) + 2
    res = get_age(5)
    print(res)

32.算法简介及二分法

1.算法就是解决问题的有效方法,例如各种软件推送

2.二分法:是算法中最简单的算法,甚至都称不上算法
"""
二分法的使用要求:带查找数据必须有序
二分法缺陷:针对开头和结尾的数据查找较慢
"""
二分法案例:
l1 = [12, 21, 32, 43, 56, 76, 87, 98, 123, 321, 453, 565, 678, 754, 812, 987, 1001, 1232]
def get_num(l, target_num):
    if len(l) == 0:
        print('很抱歉未找到您要找的数据')
        return
    middle_index = len(l)//2
    if target_num > l[middle_index]:
        right_l = l[middle_index+1:]
        get_num(right_l, target_num)
    elif target_num < l[middle_index]:
        left_l = l[:middle_index]
        get_num(left_l, target_num)
    else:
        print('找到了')
get_num(l1, 122)

33.三元表达式

1.简化步骤:代码简单并且只有一行 那么可以直接在冒号后面编写
name = 'jason'
if name == 'jason':print('老师')
else:print('学生')
    
2.三元表达式:
    数据值1 if条件 else 数据值2
    if条件执行数据值1,不成立执行数据值2

34.各种生成式/表达式/推导式

1.列表生成式

1.列表生成式:给列表每个元素加后缀:
l = ['jason', 'jerry', 'kitty', 'jerry']
new_l = [i + 'nb' for i in l]
print(new_l)  # ['jasonnb', 'jerrynb', 'kittynb', 'jerrynb']

2.列表生成式:给指定元素加后缀:
l = ['jason', 'jerry', 'kitty', 'max']
new_l = [i + '666' for i in l if i == 'jason']
print(new_l)  # ['jason666']

3.列表生成式:将不同的名字根据条件转换成其他的名字
new_l = ['大佬' if i == 'jason' else '小赤佬' for i in l]
print(new_l)  # ['大佬', '小赤佬', '小赤佬', '小赤佬']

2.字典生成式

1.enumerate(关键字)
for i, j in enumerate('hello world', start=21):
    print(i, j)
    
2.放在花括号中,可以组成一个字典,键是索引值(可以指定起始位置),值是字符串的单个元素
d = {i: j for i, j in enumerate('hello')}
print(d)  # {0: 'h', 1: 'e', 2: 'l', 3: 'l', 4: 'o'}

3.集合生成式

1.放在花括号中,用for循环取值组成集合的元素,集合的两大特性:去重、无序
set = {i for i in 'hello'}
print(set)  # {'o', 'e', 'h', 'l'}

35.匿名函数

没有名字的函数 需要使用关键字lambda
语法结构
	lambda 形参:返回值
使用场景
	lambda a,b:a+b
匿名函数一般不单独使用 需要配合其他函数一起用

36.常见的内置函数

1.map:映射(列表元素的个数不变,对每个元素按照指定的方式进行运算组成新的列表,打印时要转成列表(list()))
l1 = [1, 2, 3, 4]
res = map(lambda x:x*x, l1)
print(list(res))  # [1, 4, 9, 16]  

2.max()\min()
2.1 求列表中最大值:如果元素都是数字,会比较大小,如果是字符串会比较首字母对应的ASCII字符编码的大小
l1 = [1, 2, 3, 4]
print(max(l1))  # 4

l1 = ['Max', 'jason', 'Aj', 'zj']
print(max(l1))  # zj

2.2按字典中的值查找最大值(最小)
d1 = {
    'zj': 100,
    'jason': 8888,
    'berk': 99999999,
    'oscar': 1
	}
res = max(d1, key= lambda a:d1.get(a))
print(res)  # berk

3.reduce
	 # reduce  传多个值 返回一个值
    from functools import reduce
    l1 = [11, 22, 33, 44, 55, 66, 77, 88]
    res = reduce(lambda a, b: a * b, l1)
    print(res)

37.重要内置函数

1.zip:组成一个新的列表,列表中的元素是几个列表当中各元素组成的元组

1.1 几个列表数据值个数相等时:
l1 = [11, 22, 33, 44, 55]
l2 = ['jason', 'kevin', 'oscar', 'jerry', 'tony']
l3 = [1, 2, 3, 4, 5]
res = zip(l1, l2)
print(list(res))  # [(11, 'jason'), (22, 'kevin'), (33, 'oscar'), (44, 'jerry'), (55, 'tony')]
res1 = zip(l1, l2, l3)
print(list(res1))  # [(11, 'jason', 1), (22, 'kevin', 2), (33, 'oscar', 3), (44, 'jerry', 4), (55, 'tony', 5)]

1.2 几个列表数据值个数不相等时:
l1 = [11, 22, 33, 44, 55]
l2 = ['jason', 'kevin', 'oscar', 'jerry']
l3 = [1, 2, 3, 4, 5]
res = zip(l1, l2)
print(list(res))  # [(11, 'jason'), (22, 'kevin'), (33, 'oscar'), (44, 'jerry')]

2.filter:函数会遍历列表lst, 用lambda表达式来判断所遍历到的数据是否符合要求
l1 = [11, 32, 423, 12, 45, 32, 456, 34, 654]
res = filter(lambda x:x>100, l1)
print(list(res))  # [423, 456, 654]

l1 = [11, 32, 423, 12, 45, 32, 456, 34, 654]
res = filter(lambda  a:a > 10 and a <100, l1)
print(list(res))  # [11, 32, 12, 45, 32, 34]

3.sorted:对列表中的数据值进行排序,默认升序
l1 = [11, 32, 423, 12, 45, 32, 456, 34, 654]
res = sorted(l1) 
print(res)  # [11, 12, 32, 32, 34, 45, 423, 456, 654]
"""
排序也可以用列表的内置方法,list.sort()(如果是降序要在括号内加上reverse = True)
"""
l1.sort()
print(l1)  # [11, 12, 32, 32, 34, 45, 423, 456, 654]
l1.sort(reverse=True)
print(l1)  # [654, 456, 423, 45, 34, 32, 32, 12, 11]

38.常见的内置函数

1.abs():绝对值
print(abs(-25))  # 25
print(abs(30))  # 30

2.all():结果是一个布尔值,括号内跟一个列表,列表中全为True结果才是True,有一个为False结果就为False(类似and、'与')
print(all([1, 23, 4, 3, 2]))  # True
print(all([0, 1, 3]))  # False
print(all(['jason', 'jerry', '']))  # False

3.any():结果是一个布尔值,括号内跟一个列表,列表中全为False结果才是False,有一个为True结果就为True(类似and、'或')
print(any([1, 2, 0]))  # True
print(any([0, None, '']))  # False
"""
布尔值为False的数据类型:0、None、空字符串、空列表、空字典
"""

4.bin():转二进制 
oct():转八进制
hex():转十六进制
int():转十进制,括号内第二个参数要注明几进制

print(bin(10))  # 0b1010
print(oct(10))  # 0o12
print(hex(10))  # 0xa
print(int('0xa', 16))  # 10

5.bytes():也可以用s.encode('utf8')
s = '十一后连上七天班'
print(s.encode('utf8'))  # b'\xe5\x8d\x81\xe4\xb8\x80\xe5\x90\x8e\xe8\xbf\x9e\xe4\xb8\x8a\xe4\xb8\x83\xe5\xa4\xa9\xe7\x8f\xad'
print(bytes(s, 'utf8'))  # b'\xe5\x8d\x81\xe4\xb8\x80\xe5\x90\x8e\xe8\xbf\x9e\xe4\xb8\x8a\xe4\xb8\x83\xe5\xa4\xa9\xe7\x8f\xad'

6.callible():判断名字是否可以调用(内置函数可以、定义的函数的也可以)
name = 'jason'
print(callable(name))  # False
def index(a):
    a + 1
print(callable((index)))  # True
print(callable(print))  # True
                      
7.chr()、ord():基于ASCII码表切换数字与字母,chr():数字转字母,ord():字母转数字
print(chr(68))  # D
print(ord('A'))  # 65
"""
ASCII码表数字与字母切换:A-Z:65-90,a-z:97-122
"""

8.dir():返回括号内对象能够调用的名字
print(dir([]))  # 查询列表
print(dir('hello'))  # 查询字符串能调用的属性
print(dir(''))  # 查询字符串能调用的属性

9.divmod():括号内后面跟两个参数,第一个数被除数,第二个是除数,返回一个元祖,第一个是整除数,第二个是余数。
print(divmod(35, 2))  # (17, 1)
page_num, more = divmod(12652, 25)
if more:
    page_num += 1
print('总页码为:', page_num)  # 总页码为: 507

10.emumerate():字典生成式
放在字典里,字典的K是索引值(可以指定只是位置),字典的V是字符串的字符。
d1 = {i:j for i, j in enumerate('halle world')}
print(d1)  # {0: 'h', 1: 'a', 2: 'l', 3: 'l', 4: 'e', 5: ' ', 6: 'w', 7: 'o', 8: 'r', 9: 'l', 10: 'd'}

也可不放在字典里,分别打印i,j:
for i,j in enumerate('hello'):
    print(i, j)

11.eval()、exec():识别字符串中的代码并执行
"""
eval()和exec()直接执行前面不需要加print,加print除了打印字符串中的列表外会返回一个None
"""   
s = "print('哈哈哈')"
eval(s)  # 哈哈哈
exec(s)  # 哈哈哈

print(eval(s))  # 哈哈哈 None
print(exec(s))  # 哈哈哈 None

"""
eval()和exec()区别:eval()只能识别简单的代码,具有逻辑性的不行,exec()可以
"""
s = 'for i in range(20):print(i)'
exec(s)  # 打印0-20数字
eval(s)  # 报错

12.id():获取内存地址
    
13.input():获取用户输入
    
14.instance():第一个参数为数据值,第二个为数据类型,输出结果为布尔值,只能判断整形
print(isinstance(1, int))  # True

15.map():映射,按照指定的方式对列表中的数据进行处理,输出一个新列表,方式用lambda(匿名函数)或自定义函数来定义
l1 = [1, 2, 3, 4, 5]
res = map(lambda x:x+1, l1)
print(list(res))  # [2, 3, 4, 5, 6]

16.max()/min():
16.1.输出列表中的最大(最小值)
l1 = [1, 23, 4, 3, 2]
print(max(l1))  # 23

16.2.比较字典中的数据值
dict = {
    'jason': 100000,
    'jerry': 5000,
    'oscar': 10000,
    'kitty': 20000
}

 dict = {
    'jason': 100000,
    'jerry': 5000,
    'oscar': 10000,
    'kitty': 20000
}
def index(a):
    return dict.get(a)
res = max(dict, key=index)  # 传了函数修改了比较的依据,如果不传则会按照字符编码顺序比较
print(res)  # jason

15.open():打开文件
语法结构:
文本模式:with open (r'文件路径', 'r/w/a', encoding='utf8')

二进制模式:with open (r'文件路径', 'rb/wb/ab')

16.pow():幂指数
print(pow(2, 4)) # 16

17.range():用来确定范围的函数
range(1,10):打印1-9
range(10):打印0-9
range(1, 10, 2):间隔为2
"""
python2中的xrange和python3中的range用for循环输出一个范围都会展开每个数字,python2中是一个范围,不会展开
"""

18.round():'五舍六入'
print(round(4.2))  # 4
print(round(4.5))  # 4
print(round(4.6))  # 5

19.sum():求和:列表、集合、元组都适用
l1 = [1, 2, 3, 4]
t1 = (1, 2, 3, 4)
s1 = {1, 2, 3, 4}
print(sum(l1))  # 10
print(sum(t1))  # 10
print(sum(s1))  # 10

39.可迭代对象

1.可迭代对象:对象内有__iter__方法的都称为可迭代对象
"""
1.内置方法  通过点的方式能够调用的方法
2.__iter__  双下iter方法
"""

2.可迭代对象的范围:
    是可迭代对象的数据类型:
        str、list、dict、tuple、set、文件对象
"""
for循环支持的数据类型:str、list、dict、tuple、set,文件也支持for循环
"""
        
    不是可迭代对象:
        int、float、bool

3.可迭代的含义:
	迭代:更新换代 eg:手机app更新
	可迭代对象在python中可以理解为是否支持for循环

40.迭代器对象

1.迭代器对象:
    是由可迭代对象调用__iter__方法产生
    迭代器对象判断的本质是看是否有__iter__和__next__(两者必须都有)
    
2.迭代器对象的作用
	提供了一种不依赖于索引取值的方式,正因为有迭代的存在,我们的字典,集合才能否被for循环
    
3.迭代器对象实操
s = 'hello'
res = s.__iter__()
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())  # 会依次打印'hello'
print(res.__next__())  # 再执行会报错,而for循环不会
"""
__next__取不到值会直接报错
"""
print(s.__iter__().__next__())
print(s.__iter__().__next__())
print(s.__iter__().__next__())
print(s.__iter__().__next__())
print(s.__iter__().__next__())  # hhhhh
"""
会连打5个h,因为每次调用可迭代对象并且变成迭代器对象,所以每次都会重新执行
"""

4.注意事项:
    可迭代对象调用__iter__会成为迭代器对象,迭代器对象如果还调用__iter__不会有任何变化,还是迭代器对象本身

41.for循环本质:

for 变量名 in 可迭代对象:
    循环体代码
"""
1.先将in后面的可迭代对象用__iter__转变成迭代器对象
2.依次让迭代器调用__next__取值
3.一旦__next__取不到值报错,for循环会自动捕捉并处理,所以我们不会看到for循环报错
"""

42.异常捕获/处理

1.异常
	异常就是代码运行报错 行业俗语叫bug
	代码运行中一旦遇到异常会直接结束整个程序的运行 我们在编写代码的过程中药尽可能避免
2.异常分类
	语法错误
    	不允许出现 一旦出现立刻改正 否则提桶跑路
	逻辑错误
    	允许出现的 因为它一眼发现不了 代码运行之后才可能会出现
3.异常结构
	错误位置
 	错误类型
 	错误详情

43.作业

1.判断下列money的值是多少并说明理由 思考如何修改而不是新增绑定关系
money = 100
def index():
    money = 666

print(money)  #100 print打印的是全局名称空间中的money
   

money = 100
def func1():
    money = 666
    def func2():
        money = 888
    func2()
print(money)  # 100 print打印的是全局名称空间中的money
如果想在局部名称空间中修改全局名称空间中的变量名,需要用到后面所学的关键字:global
    
2.编写一个用户认证装饰器
  函数:register login transfer withdraw 
  基本要求
   	 执行每个函数的时候必须先校验身份 eg: jason 123
  拔高练习(有点难度)
   	 执行被装饰的函数 只要有一次认证成功 那么后续的校验都通过
  提示:全局变量 记录当前用户是否认证

基本要求
def outer(func):
    def inner(*args, **kwargs):
        user_name = input('请输入您的用户名>>>:').strip()
        user_pwd = input('请输入您的密码>>>:').strip()
        if user_name == 'jason' and user_pwd == '123':
            print('登陆成功')
            res = func(*args, **kwargs)
            return res
        else:
            print('用户名或密码错误')
    return inner

@outer
def register():
    print('注册功能')
@outer
def login():
    print('登录功能')
@outer
def transfer():
    print('转账功能')
@outer
def withdraw():
    print('提现功能')

register()
login()
transfer()
withdraw()

拔高练习
is_login = False


def outer(func):
    def inner(*args, **kwargs):
        global is_login
        if is_login:
            res = func(*args, **kwargs)
            return res
        user_name = input('请输入您的用户名>>>:').strip()
        user_pwd = input('请输入您的密码>>>:').strip()
        if user_name == 'jason' and user_pwd == '123':
            print('登陆成功')
            is_login = True
            res = func(*args, **kwargs)
            return res
        else:
            print('用户名或密码错误')

    return inner


@outer
def register():
    print('注册功能')


@outer
def login():
    print('登录功能')


@outer
def transfer():
    print('转账功能')


@outer
def withdraw():
    print('提现功能')


register()
login()
transfer()
withdraw()

3.利用递归函数依次打印列表中每一个数据值
	l1 = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]
l1 = [1, [2, [3, [4, [5, [6, [7, [8, ]]]]]]]]
def index(l):
    for i in l:
        if isinstance(i, int):
            print(i)
        else:
            index(l[1])
index(l1)


4.利用有参装饰器编

写多种用户登录校验策略
def login_auth(mode):
    def outer(func):
        def inner(*args, **kwargs):
            user_name = input('请输入您的用户名>>>:').strip()
            user_pwd = input('请输入您的密码>>>:').strip()
            if mode == 'absolute':
                if user_name == 'jason' and user_pwd == '123':
                    print('登陆成功')
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('用户名或密码错误')
            elif mode == 'from_list':
                user_list = ['jason|123', 'kevin|321', 'tony|222']
                for data in user_list:
                    real_name, real_pwd = data.split('|')
                    if user_name == real_name and user_pwd == real_pwd:
                        print('登陆成功')
                        res = func(*args, **kwargs)
                        return res
                else:
                    print('用户名或密码错误')
            elif mode == 'from_doc':
                with open (r'userinfo.txt', 'r', encoding='utf8') as f1:
                    for line in f1:
                        doc_name, doc_pwd = line.split('|')  # jason|123\n
                        if user_name == doc_name and user_pwd == doc_pwd.strip('\n'):
                            print('登陆成功')
                            res = func(*args, **kwargs)
                            return res
                    else:
                        print('用户名或密码错误')
        return inner
    return outer


@login_auth('absolute')
def index():
    print('账户唯一')


@login_auth('from_list')
def func1():
    print('账户信息来自列表')


@login_auth('from_doc')
def foo():
    print('账户信息来自文件')

# index()
# func1()
# foo()


5.有下列用户数据
    user_data = {
        '1': {'name': 'jason', 'pwd': '123', 'access': ['1', '2', '3']},
        '2': {'name': 'kevin', 'pwd': '321', 'access': ['1', '2']},
        '3': {'name': 'oscar', 'pwd': '222', 'access': ['1']}
    }
    并有三个函数
        def func1():
            pass
        def func2():
            pass
        def func3():
            pass
    要求:调用上述三个函数的时候需要从user_data中校验用户身份是否正确
    并获取当前登录用户拥有的可执行函数功能编号即键access对应的功能编号列表
    func1是1、func2是2、func3是3
    并且一旦用户登录成功之后后续函数的调用不再校验用户身份
    请思考如何获取函数功能编号 如何校验用户身份 如何校验权限
    ps:装饰器知识         附赠:实现上述主体功能即可 其他扩展优化功能可暂且不写
            
user_data = {
        '1': {'name': 'jason', 'pwd': '123', 'access': ['1', '2', '3']},
        '2': {'name': 'kevin', 'pwd': '321', 'access': ['1', '2']},
        '3': {'name': 'oscar', 'pwd': '222', 'access': ['1']}
    }
is_login = {
    'absolute': False,
    'login_access': 0
}
def login_auth(mode):
    def outer(func):
        def inner(*args, **kwargs):
            if is_login.get('absolute'):
                if mode in is_login.get('login_access'):
                    res = func(*args, **kwargs)
                    return res
            user_id = input('请输入您的用户编号>>>:')
            if user_id not in user_data:
                print('您的账户未注册')
                return
            user_name = input('请输入您的用户名>>>:')
            user_pwd = input('请输入您的密码>>>:')
            if user_name == user_data.get(user_id).get('name') and user_pwd == user_data.get(user_id).get('pwd'):
                if mode in user_data.get(user_id).get('access'):
                    is_login['absolute'] = True
                    is_login['login_access'] = user_data.get(user_id).get('access')
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('您无权执行此操作')
            else:
                print('用户名或密码错误')
        return inner
    return outer

@login_auth('1')
def func1():
    print('from func1')

@login_auth('2')
def func2():
    print('from func2')

@login_auth('3')
def func3():
    print('from func3')

func1()
func2()
func3()

44.周测

理论考核篇
1.你所使⽤过的⽂本编辑器有哪些
 其中Typora有何特点并简单列举⼏个语法功能
    
文本编辑器:word,typora,印象笔记;
Typora特点:界面简洁,在IT行业应用广泛,适用于不同语言环境。
语法功能:(1)有序标题:井号(几级标题就用几个井号) + 标题文字
(2)无序标题:+ + 空格 + 标题文字
(3)语言环境:```+语言环境名称
    
2.什么是编程语⾔,编程的本质是什么
编程语言是人与计算机沟通交流的媒介
编程的本质是用计算机能够读懂的语言与计算机交流,编程的结果是产生一堆文件

3.计算机五⼤组成部分及各⾃主要功能
(1)控制器:控制计算机各部分硬件的工作;(2)运算器:负责数学运算和逻辑运算;(3)存储器:记忆和存储数据;(4)输入设备:将信息传递给计算机的设备,例如鼠标键盘;(5)输出设备:计算机将信息传递给外界的设备:例如显示器,音响等
                        
4.计算机三⼤核⼼硬件及详述三者⼯作关系
(1)CPU:控制器+运算器=CPU,对计算机各部分的工作进行控制、运算;(2):内存:运行速度快,基于电工作,断电数据会立刻丢失;(3):硬盘:不基于电工作,断电数据不会立刻丢失,运行速度较内存慢,但可以长期保存数据。双击一款软件时系统会将软件代码从硬盘刷到内存,CPU会在内存当中读取软件的数据。
                    
5.简述计算机底层存储数据原理及编程语⾔发展史、分类
计算机存储数据的原理:计算机是将数据类型以二进制的方式进行存储。
编程语言的发展史:(1):机器语言:用机器能读懂的语言与计算机交流,开发效率低,门槛高,执行效率高。(2):汇编语言:用字母代替二进制数字与计算机交流,开发效率较低,执行效率较高,但是门槛还是太高。(3):高级语言:用人类能够读懂的语言与计算机进行交流,门槛较低,开发效率较高。
编程语言的分类:(1)编译型:类似于谷歌翻译,一次性编译及可以反复使用,效率高,缺点是如果遇到bug需要重复编译。代表语言:C++(2):解释型:类似于同声传译,有误bug对执行效率没有影响
                    
6.python解释器版本特点,如何实现多版本共存:
版本特点:python2.7:较老的项目使用;python3.6:较稳定;python3.8:较新的项目使用
如何实现多版本共存:下载解释器之后拷贝文件夹内的python.exe文件,粘贴后重命名,名字要独一无二。
    
7.常⻅的编程软件有哪些,你更倾向于哪个简单说说缘由
sublime、vosode、pycharm;我更倾向于pycharm,因为它界面简洁,对小白更友好

8.什么是注释,python中如何编写注释
注释是对一串代码的解释说明;python中单行注释需要在注释前加井号,如果是在一行代码的后面加注释要注意代码和井号之间空两格,井号和注释之间空一格。多行注释可以用三个单引号或者三个双引号来引用。

9.什么是变量、如何定义变量、阐述内部本质
变量是时长变化的量;定义变量需要将变量用赋值符号和数据值相连,变量名在左数据值在右,如果赋值符号右边是变量名那么首先应该找到该变量名指代的数据值。本质:在内存当中申请一块地址存放该数据值,并且把该数据值和变量名临时绑定,此后通过变量名就可以直接找到数据值。
    
10.变量的命名规范与命名⻛格
变量名的命名规范:变量名可以用数字、字母下划线,但是数字不能开头;变量名可以使用汉字、拼音但是不建议;变量名不能和关键字重复;变量名要做到见名知意;命名风格:下划线式:python推荐使用,eg:user_name;驼峰体式:JS推荐使用。eg:大驼峰:UserFromDict,小驼峰:userFromDict
                                
11.什么是垃圾数据,简单聊聊python中的垃圾回收机制
垃圾数据:就是没有变量名绑定并且无用的数据。垃圾回收机制:(1):引用计数:是数据值被变量名引用的次数,如果数据值的引用计数为0就会被垃圾回收机制清楚;(2):标记清除:当内存使用快要达到极限时,首先会对循环引用的数据进行标记并且一次性清除;(3):分代回收:系统会根据对数据的检索频率把数据分成'新生代'、'青春代'、'老年代',数据值被引用的次数越来越高,数据检索频率会越来越低,该数据越重要不会被系统清除。相反数据则会被系统检索并且清除
                                
12.列举你所知道的python基本数据类型及各⾃表现形式
字符串:str,支持索引,切片操作,for循环;整形:int,整数;浮点型:float,小数;列表:中括号括起来,list,索引取值,支持切片,for循环;dict:字典:花括号括起来,元素是K:V键值对,按K取值,支持for循环;集合:set,花括号括起来,内部数据无序,用来去重、关系运算;元组:tuple,小括号括起来,不可变的列表,是不可变类型。
 
代码实战
1.编写⽤户识别程序
 要求:
 可循环根据⽤户输⼊的姓名不同输出不同的身份信息
 添加程序结束功能(如⽤户输⼊字⺟q直接结束识别程序)
 jason:扫地僧 tony:洗碗⼯ kevin:服务员 jack:配菜员 其他:
未识别
while True:
    choice = input('请输入您的姓名(q)>>>:')
    if choice == 'q':
        print('欢迎下次光临')
        break
    if choice == 'jason':
        print('扫地僧')
    elif choice == 'tony':
        print('洗碗工')
    elif choice == 'kevin':
        print('服务员')
    elif choice == 'jack':
        print('配菜员')
    else:
        print('未识别')
        
2.利⽤for循环及range⽅法⾃动⽣成链家⼆⼿房多⻚数据⽹址(⼗条以
上即可)
 初始⽹址:https://sh.lianjia.com/ershoufang/      
'''
通过前几页可得:
page1:https://sh.lianjia.com/ershoufang/pg1/
page2:https://sh.lianjia.com/ershoufang/pg2/
page3:https://sh.lianjia.com/ershoufang/pg3/
page4:https://sh.lianjia.com/ershoufang/pg4/
'''
s = 'https://sh.lianjia.com/ershoufang/pg%s/'
for i in range(1, 12):
    print(s % i)

3.编写⽤户登录程序
 温馨提示:
 ⽤户名与密码来源于字符串source_data = 'jason|123'
 想办法从中拆分出⽤户名和密码⽤于后续账户信息⽐对
 普通要求:
 1.验证失败情况下可⼀直循环验证 成功则直接退出
 拔⾼练习:
 1.只允许三次失败机会
 2.登录成功后进⼊内层循环,⽤户输⼊任何指令利⽤格式化输出
 打印正在执⾏该⽤户指令即可,直到⽤户输⼊字⺟q退出内层循环
# 普通要求
source_data = 'jason|123'
while True:
    user_name = input('请输入您的用户名>>>:').strip()
    user_pwd = input('请输入您的密码>>>:').strip()
    real_name, real_pwd = source_data.split('|')
    if user_name == real_name and user_pwd == real_pwd:
        print('登陆成功')
        break
    else:
        print('用户名或密码错误')
        
# 拔高练习
is_continue = True
count = 1
source_data = 'jason|123'
while is_continue:
    if count == 4:
        print('您已输入错误三次!')
        break
    user_name = input('请输入您的用户名>>>:').strip()
    user_pwd = input('请输入您的密码>>>:').strip()
    real_name, real_pwd = source_data.split('|')
    if user_name == real_name and user_pwd == real_pwd:
        print('登陆成功')
        while is_continue:
            user_order = input('请输入您的指令(q)>>>:')
            if user_order == 'q':
                print('欢迎下次光临')
                is_continue = False
                break
            print('正在执行你的指令%s' % user_order)
    else:
        print('用户名或密码错误')
        count += 1

原文地址:http://www.cnblogs.com/zkz0206/p/16797513.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性