python学习笔记

2020-01-04

python学习笔记

第一章 计算机基础

1.1 硬件

计算机基础的硬件: CPU/内存/主板硬盘/网卡/显卡等组成,只有硬件当硬件之间无法进行交流和通信

1.2 操作系统

操作系统用于协同或控制硬件之间进行工作,常见的操作系统有哪些

  • windows

  • linux

    • centos[公司上线一般用]

  • mac

1.3 解释器或编译器

编程语言的开发者写的一个工具,将用户写的代码转换成010101交给操作系统去执行。

1.3.1 解释和编译型语言

解释型语言就类似于: 实时翻译,代表: Python/PHP/Ruby/Perl

编译型用于类似于: 说完之后,整体再进行翻译,代表:C/C++/java/GO

1.4 软件(应用程序)

软件又称为应用程序,就是我们在电脑上使用的工具,类似于:记事本/图片查看/游戏

1.4 进制

对于计算机而言无论是文件存储/网络传输输入本质上都是: 二进制(010101010101),如:电脑上存储视频/视图/文件都是二进制;QQ/微信聊天发送的表情/文字/语言/视频也全部都是二进制.

进制:

  • 2进制,计算机内部

  • 8进制

  • 10进制,人来进行使用,一般情况下计算机可以获取10进制,然后在内部会自动转换为二进制并操作。

  • 16进制,一般用于表示二进制(ong更短的内容表示更多的数据),一般是: \x开头.

第二章 Python基础

2.1 环境的安装

  • 解释器: py2/py3 (环境变量)

  • 开发工具: pycharm

2.2 编码

2.2.1 编码基础
  • ASCII

  • Unicode

  • utf-8

  • gbk

  • gb2312

2.2.2 python 编码相关

对于Python默认解释器编码:

  • py2: ascii

  • py3: utf-8

如果想要修改默认编码,则可以使用:

 #!/usr/bin/env python
 # -*- coding:utf-8 -*-

  

注意: 对于操作文件时,要按照:以什么编码写入,就要用什么编码去打开。

2.3 变量

为了复用,才有变量,只用一次的没有必要用变量

 

 

第三章 数据类型

3.1 整型(int)

3.1.1 整型的长度
python2 : int 和 long 
python3 : int 

  

3.1.2 整除
 # python2 中使用除法,只能保留整数位,如果要保留小数位:
 from __future__ import division 
 value = 3/2
 print(value) 
 # python3 中/是保留小数的,想要只保留整数位,则使用//

 

3.2 布尔型 (bool)

python语法 人类语言 计算机语言
True 1
False 0
布尔值转换

除了None""0[]{},()转换为布尔值为False外,其他数据都为True

3.3 字符串(str)

Python的字符串是按照Unicode编码存储的;

字符串不可变;

3.3.1 转为大写
# 转为大写
 v = 'nbchen'
 print(v.upper()) # NBCHEN

 

3.3.2 转为小写
 v = 'NBchen'
 print(v.lower()) # nbchen

 

python3 引入了另一个更强的方法。 casefold()

lower() 方法只对ASCII编码,也就是‘A-Z’有效,对于其他语言(非汉语或英文)中把大写转换为小写的情况只能用 casefold() 方法

 S2 = "ß"  # 德语
 print(S2.casefold())  # 德语的"ß"正确的小写是"ss"

 

3.3.3 是否全部为大写
 v = 'NBCHEN'
 print(v.isupper()) # True

 

3.3.4 是否全部为小写
 v = 'nbchen'
 print(v.islower()) # True

 

3.3.5 首字母大写
 v = 'nbchen'
 print(v.capitalize()) # Nbchen

 

3.3.6 大小写转换
 v = 'NBchen'
 print(v.swapcase()) # nbCHEN

 

3.3.7 以什么开头
 v = 'NBchen'
 print(v.startswith('NB')) # True

 

3.3.8 以什么结尾
 v = 'NBchen'
 print(v.endswith('chen')) # True

 

3.3.9 统计出现次数
 v = 'NBchen'
 print(v.count('n')) # 1

 

3.3.10 查找下标
 v = 'nbchen'
 print(v.find('n'),v.find('s'),v.rfind('n')) # 0[默认从左开始找] -1[未找到] 5[从右开始找]

 

3.3.11 判断是否为数字
 v1 = '1'
 v2 = ''
 v3 = ''
 print(v1.isdigit(),v1.isdecimal(),v1.isnumeric())
 print(v2.isdigit(),v2.isdecimal(),v2.isnumeric())
 print(v3.isdigit(),v3.isdecimal(),v3.isnumeric())
 """
 方法/变量    isdigit    isdecimal    isnumeric
 '1'         True        True        True
 '二'         False       False       True
 '②'         True        False       True
 """
 # 所以推荐用 isdecimal 判断是否为 10 进制的数

 

除了判断数字外,还有方法:

判断是不是数字和字母

 v = "nbchen2019"
 print(v.isalnum()) # True

 

判断是不是纯字母和汉字

 v = "nbchen陈老大的猫"
 print(v.isalpha()) # True

 

3.3.12 去除空白
 # ps: \n 换行符 \t制表符
 v = ' NBchen\t\n'
 print(v.strip()) # NBchen

 

strip除了可以去除空白,还有换行,制表符,还可以指定字符去除

 v = 'nbchen'
 print(v.strip('n'),v.strip('nb')) # bche che

 

3.3.13 替换
 v = 'nbchen'
 print(v.replace('n','c')) # cbchec
3.3.14 编码
 v = "陈老大的猫"
 print(v.encode('utf-8')) # b'\xe9\x99\x88\xe8\x80\x81\xe5\xa4\xa7\xe7\x9a\x84\xe7\x8c\xab' 

 

3.3.15 分割
 v = "陈老大,的猫"
 print(v.split(',')) # ['陈老大', '的猫']

 

除了上面,还有分区方法:

 v = "陈,老,大,的,猫"
 print(v.split(',')) # ['陈', '老', '大', '的', '猫']
 print(v.partition(',')) # ('陈', ',', '老,大,的,猫')
 print(v.rpartition(',')) # ('陈,老,大,的', ',', '猫')

 

3.3.16 格式化
 v = "陈老大的猫:{}"
 print(v.format ('任建宁')) # 陈老大的猫:任建宁

 

还可以用这种方法:

 v = "{master}的猫:{sweeter}"
 print(v.format_map({'master': '陈老大', 'sweeter': '任建宁'})) # 陈老大的猫:任建宁

 

3.3.17 长度
 v = "陈老大的猫"
 print(len(v)) # 5

 

3.3.18 拼接
 v = "陈老大的猫"
 print(','.join(v)) # 陈,老,大,的,猫

 

3.3.19 填充
 v = "陈老大的猫"
 print(v.center(20,'*')) # *******陈老大的猫********

 

填充除了居中,

还有居左

 v = "nbchen"
 print(v.ljust(20,'*')) # nbchen**************

 

居右

 v = "nbchen"
 print(v.rjust(20,'*')) # **************nbchen

 

还有别的方法:

 v = "nbchen"
 print(v.zfill(20)) # 00000000000000nbchen
 # 比上面的方法要弱,只能补0

 

3.3.20 去除\t制表符
 v = "n\tb\tchen"
 print(v.expandtabs(tabsize=0)) # nbchen [tabsize默认为8]

 

3.3.21 是否可以打印
 v = "\t"
 print(v.isprintable()) # False

 

3.3.22 是否是空白
 v = " "
 print(v.isspace()) # Truev.isprintable()

 

3.3.23 首字母是否是大写
 v = "Nbchen Is Nb"
 print(v.istitle()) # True

 

3.3.24 转换过滤
 a = "chen"
 b = "1234"
 table = str.maketrans(a,b) # 将c映射为1,h映射为2,e映射为3,n映射为4
 print(table) # {99: 49, 104: 50, 101: 51, 110: 52}
 ​
 v = 'nbchen'
 print(v.translate(table)) # 根据上面的映射表,转为为最终的字符串: 4b1234

 

3.4 列表(list)

3.5 元组 (tuple)

3.6 字典 (dict)

3.7 集合 (set)

3.8 公共方法

  • len

  • 索引

  • 切片

  • 步长

  • for循环

3.9 嵌套

第四章 文件操作

4.1 文件基本操作

 # 打开 -> 操作-> 关闭
 obj = open('路径',mode='模式',encoding='编码')
 obj.write()
 obj.read()
 obj.close()

 

4.2 打开模式

  • r / w / a

  • r+ / w+ / a+

  • rb / wb / ab

  • r+b / w+b / a+b

4.3 具体操作

  • read() : 全部读到内存

  • read(1)

    • 1 表示一个字符

     # log.txt 文件内容: 
     '''
     测试文件读取
     '''
     obj = open('log.txt',mode='r',encoding='utf-8')
     data = obj.read(1) # read(1)在r模式下: 读一个字符
     obj.close()
     print(data) #
    View Code

     

    • 1 表示一个字节

     obj = open('log.txt',mode='rb')
     data = obj.read(3) # read(1)在rb模式下: 读一个字节
     obj.close()
     print(data) # b'\xe6\xb5\x8b'
     print(data.decode('utf-8')) #
    View Code

     

  • write(字符串) :

    obj = open('log.txt',mode='w',encoding='utf-8')
     data = obj.write('插进去') # write(字符串)在w模式下写入
     obj.close()
     # log.txt 被插入后 :
     '''
     插进去
     '''
    View Code

     

  • write(二进制) :

     obj = open('log.txt',mode='wb')
     data = obj.write('再插进去'.encode('utf-8')) # write(字符串编码为二进制)在wb模式下写入
     obj.close()
     # log.txt 被插入后 :
     '''
     再插进去
     '''
    View Code

     

  • seek : 光标字节位置, 无论模式是否带b,都是按照字节进行处理

  • tell :获取当前光标所在的字节位置

     
    # log.txt 内容:
     '''
     再插进去
     '''
     obj = open('log.txt',mode='r',encoding='utf-8')
     obj.seek(3) # 光标在第三个字节的位置
     position = obj.tell() #  获取当前光标所在的字节位置
     data = obj.read()
     obj.close()
     print(data, position) # 插进去 3
     # ps : 断点续传,本质上是根据seek,tell
    View Code

     

  • flush : 强制将内存中的数据写入硬盘

     
    # log.txt 内容:
     '''
     再插进去
     '''
     obj = open('log.txt',mode='a',encoding='utf-8')
     while True:
         v = input("请输入: ") # 输入: 我插入、  我再插入
         obj.write(v)
         obj.flush() # 结果 : 再插进去我插入、我再插入
     obj.close()
    View Code

     

4.4 关闭文件

 
# 文艺
 obj = open('log.txt',mode='r',encoding='utf-8')
 data = obj.read() 
 obj.close()
 # 二逼
 with open('log.txt',mode='r',encoding='utf-8') as v: 
     data = v.read() 
 # with as 操作完后自动关闭文件
View Code

 

4.5 文件的修改

 
# log.txt 内容:
 '''
 再插进去
 '''
 with open('log.txt',mode='r',encoding='utf-8') as obj:
     data = obj.read()
 print(data) # 再插进去
 new_data = data.replace('','第一次')
 with open('log.txt',mode='w',encoding='utf-8') as obj:
     obj.write(new_data)
 # log.txt 修改后的内容:
 '''
 第一次插进去
 '''
 # ps: 上面这种,全部读到内存,如果文件太大,就会撑爆内存
View Code

 

大文件修改:

 
# log.txt 内容:
 '''
 第一次插进去
 '''
 f1 = open('log.txt',mode='r',encoding='utf-8')
 f2 = open('log2.txt',mode='w',encoding='utf-8')
 for line in f1:
     new_line = line.replace('','')
     f2.write(new_line)
 f1.close()
 f2.close()
 # log2.txt 内容:
 '''
 第二次插进去
 '''
 # 简写:
 with open('log.txt',mode='r',encoding='utf-8') as f1, open('log2.txt',mode='w',encoding='utf-8') as f2:
     for line in f1:
         new_line = line.replace('', '')
         f2.write(new_line)
View Code

 

 

第五章 函数

传参:位置参数>关键字传参

函数不被调用,内部的代码永远不会执行

每次调用函数时,都会为此次调用开辟一块内存,内存可以保存自己以后想要用的值

函数是作用域,如果自己作用域中没有,则往上级作用域找

5.1 三元运算

 if 条件:
     v = '前面'
 else: 
     v = '后面'
 ​
 # 转为三目运算:
 v = 前面 if 条件 else 后面
 ​
 # 让用户输入值,如果是整数,则转为整数,饭后则赋值为None
 data = input('>>')
 v = int(data) if data.isdecimal() else None
 print(v)

  

5.2 函数基础使用

面向过程编程可读性和可重用性差

5.2.1 函数定义,调用
 
# 发送邮件封装
 import smtplib
 from email.mime.text import MIMEText
 from email.utils import formataddr
 ​
 def send_email():  # 定义
     msg = MIMEText('我爱你', 'plain', 'utf-8')
     msg['Form'] = formataddr(["发送人的名字",'发送人的邮箱'])
     msg['To'] = formataddr(["被发送人名字","被发送人的邮箱"])
     msg['Subject'] = "主题"
     
     server = smtplib.SMTP("smtp@163.com", 25)
     server.login("发送人的邮箱", "密码")
     server.sendmail("发送人的邮箱", ['被发送人的邮箱', ], msg.as_string())
     server.quit()
 ​
 send_email() # 调用
 # 如果发送不成功,可能是网易开了客户端授权密码,关闭即可 
View Code

 

网上的案例

5.2.2 函数的参数

形参,实参

函数参数传递是内存地址(引用/值)

 def join_list(a1, a2):
     result = []
     result.extend(a1)
     result.extend(a2) # extend 拼接
     print(result) # [11, 22, 33, 44, 55, 66]
 join_list([11, 22, 33], [44, 55, 66])
View Code

 

5.2.3 函数的返回值
 
def join_list(a1, a2):
     result = []
     result.extend(a1)
     result.extend(a2)
     return result  # return 返回值; 不写默认return None
 v = join_list([11, 22, 33], [44, 55, 66])
 print(v) # [11, 22, 33, 44, 55, 66]
# 练习1.让用户输入一段字符串,计算字符串中有多少A字符的个数,有多少个就在文件a.txt中写多少个'嘻'
 def get_char_count(data):
     sum = 0
     for i in data:
         if i == 'A':
             sum += 1
     return sum
 ​
 def write_file(line):
     if len(line) == 0:
         return False
     with open('temp.txt',mode='w',encoding='utf-8') as f:
         f.write(line)
     return True
 ​
 content = input("请输入:")
 count = get_char_count(content)
 write_data = '' * count
 status = write_file(write_data)
 if status:
     print("写入成功")
    
 # 特殊,返回元组
 def test():
     return 1,'3',['43','ni']
 v = test()
 print(v) # (1, '3', ['43', 'ni'])
View Code

 

5.2.4 函数的练习

 # 3.读取文件,将文件的内容构造成指定格式的数据,并返回
 """
 a.log 
     nbchen|23|175
     Chen老大的猫|3|61
 目标:
 a. ['nbchen|23|175','Chen老大的猫|3|61']并返回
 b. [['nbchen','23','175'],['Chen老大的猫','3','61']]
 c. [
     {'name':'nbchen','age':'23','height':'175'},
     {'name':'Chen老大的猫','age':'3','height':'61'}
     ]
 """print("开始读取文件")
 def get_str_2_list():
     with open('a.log',mode='r',encoding='utf-8') as f:
         list = []
         for line in f:
             print("每一行的内容%s" % (line, ))
             list.append(line.strip())
     return list
 v = get_str_2_list()
 print("读取的集合:",v,"\n=======================")
 a = v # 第一题
def get_list_format(list):
     new_list = []
     for i in range(0,len(list)):
         t = list[i].split('|')
         print("切割后得到数据:",t)
         new_list.append(t)
     return new_list
 v = get_list_format(v)
 print("格式化的集合:", v , "\n=======================")
 b = v # 第二题
def list_format_map(list):
     v = ['name','age','height']
     list_dic = []
     for item in range(0,len(list)):
         dic = {}
         print("集合中的每一项:", list[item])
         for i in range(0, len(list[item])):
             print("集合中的子集合的每一项:", list[item][i])
             print("字典的每个key:",v[i])
             dic[v[i]]= list[item][i]
             print("集合中的子集合的每一项映射到字典:",dic)
         list_dic.append(dic)
     return list_dic
 v = list_format_map(v)
 print("格式化后的字典: ",v)
 c = v #  第三题
# 耗时:35分钟
View Code

 

5.2.4 函数的作用域

python中一个函数是一个作用域;

java中一个代码块是一个作用域;

5.2.4.1 作用域赋值

  • 子作用域中只能找到父级中的值,无法重新为父级的变量进行赋值

     
    name = 'nbchen'
     def func():
         name = '陈老大的猫' # 在自己的作用域在创建一个这个的值
         print(name) # 陈老大的猫
     func()
     print(name) # nbchen
    # 列表修改的是里面的,字符串不可变.
     name = ['nbchen', '陈老大的猫']
     def func():
         name.append('陈某某')
         print(name) # ['nbchen', '陈老大的猫', '陈某某']
     func()
     print(name) # ['nbchen', '陈老大的猫', '陈某某']
    View Code

     

  • 如果非要对全局的变量进行赋值

     
    name = 'nbchen'
     def func():
         global name  
         name = '陈老大的猫'
         print(name) # 陈老大的猫
     func()
     print(name) # 陈老大的猫
    # 注意global改的是全局的,nolocal改的是上一级的.如果函数嵌套的时候,就要注意下
    View Code

     

     

 

5.2.5 函数的嵌套
5.2.6 关键字传参
 # 默认函数参数按顺序的,
 # 如果想要不按顺序传参,可以指定关键字即可
 def func(a1,a2):
     print(a1,a2) # 2 1
 func(a2=1,a1=2)
 ​
 # 传参和位置传参混用的时候,必须关键字传参在后面,而且,注意顺序
 def func(a1,a2,a3):
     print(a1,a2,a3) # 1 3 4
 func(1,a2=3,a3=4)
View Code

 

5.2.7 默认参数(定义时)
 
# 设置默认值后,参数可传可不传
 # 看open源码:
 def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
 # ps: 默认参数如果是不可变类型,随便玩,如果是可变类型,这里会有个坑

 

5.2.8 动态参数
 
# 动态接收位置参数
 def eat(*args):
     print('我想吃',args)
 eat('大米饭','中米饭','小米饭')  # 收到的结果是一个tuple元祖
# 不确定要接收多少个参数的时候,可以用动态参数
 # 动态参数必须放在位置参数,默认参数后面
# 最终顺序:
 # 位置参数 > args(动态位置参数) > 默认值参数 > *kwargs(动态默认参数)
# 综合使用:
 def func(*args,**kwargs):
     print(args,kwargs)
 func(1,23,5,a=1,b=6)
 func(1,*[23,5],**{a=1,b=6})
View Code

 

5.3 函数高级

5.3.1 函数的赋值
 
def func():
     print(123)
 v1 = func
 func()
 v1()
 ​
 # 也可以放到列表[]里面,还可以放到集合{}里面,但是也注意去重的效果。
 func_list = [func,func,func]
 for item in func_list:
     item()
     
 # 也可以放到字典{}里面
 def func():
     print('1')
 dic = {'k1':func,'k2':func}
 dic['k1']()
 ​
 # 函数名可以当做变量使用,当前参数传递
View Code

 

优雅的根据输入的参数执行函数的方式

 def test1():
     print('test1')
 def test2():
     print('test2')
 def test3():
     print('test3')
 def test4():
     print('test4')
 info = {
     'f1': test1,
     'f2': test2,
     'f3': test3,
     'f4': test4
 }
 choice = input("请选择要选择功能:")
 function_name = info.get(choice)
 if function_name:
     function_name()
 else: 
     print("输入错误")
View Code

 

5.3.2 函数闭包
 # 关键: 函数是由谁创建的,就从哪里开始找
 """
 name = 'nbchen'
 def base():
     print(name) # nbchen
 def func():
     name = '陈老大的猫'
     base()
 func()
 """"""
 name = 'nbchen'
 def func():
     name = '陈老大的猫'
     def base():
         print(name)  # 陈老大的猫
     base()
 func()
 """
View Code

 

 '''
 info = []
 def func():
     print(item)
 for item in range(10):
     info.append(func)
 info[0]() 
 # 9
 '''
 ​
 info = []
 def func(i):
     def inner():
         print(i)
     return inner
 for item in range(10):
     info.append(func(item))
 info[0]() # 0
View Code

 

5.4 lambda表达式

 
def func(a1,a2):
     return a1 + a2
 # 使用lambda
 func = lambda a1,a2 : a1 + a2 # 默认将运算的结果return回来
 func = lambda : 100 # 无参,返回100
 func1 = lambda x1: x1 * 100
 func2 = lambda *args,**kwargs: len(args)+len(kwargs)
 ​
 print(func()) # 100
 print(func1(2)) # 200
 print(func2(1, 2, 3)) # 3
View Code

 

ps: lambda内部不能自己创建变量,只能用传递过来你的,或者找父级的变量

python lambda和java中的不太一样,别混淆了。

5.5 内置函数

5.5.1 强制转换
  • 输入输出

    • print()

    • input()

  • 强制转换

    • dict()

    • list()

    • set()

    • tuple()

    • int()

    • str()

    • bool()

  • 数学

    • abs()

    • min()

    • max()

    • round()

    • float()

    • sum()

    • pow()

    • divmod() : 2个数相除,得商和余数

       
      a,b = divmod(100,3)
       print(a,b) # 33,1
      # 分页小李子
       USER_LIST = []
       for i in range(1,16):
           temp = {'name': '插入第%s次'%i,'count':'嗯*%s'%i}
           USER_LIST.append(temp)
       ​
       # 数据总条数
       total_count = len(USER_LIST)
       ​
       # 每页显示10条
       per_page_count = 10# 总页码数
       max_page_num,a = divmod(total_count,per_page_count)
       if a > 0:
           max_page_num += 1
       while True:
           pager = int(input('要查看第几页(1 ~ %s):'%max_page_num))
           if pager < 1 or pager > max_page_num:
               print('页码不合法,必须是1 ~ %s'%max_page_num)
           else:
               start = (pager - 1) * per_page_count
               end = pager * per_page_count
               data = USER_LIST[start:end]
               for item in data:
                   print(item)
      View Code

       

  • 进制

    • bin() : 将10进制转为2进制

    • oct() : 将10进制转为8进制

    • int() : 将2/8/16进制转为10进制

    • hex() : 将10进制转为16进制

  • 编码

    • chr() : 将十进制数字转换成Unicode编码中的对应字符串

    • ord() : 根据字符在Unicode编码中找到其对应的十进制

       import random
       
       # 随机生成验证码
       def get_random_code(length = 6):
           data = []
           for i in range(length):
               v = random.randint(65,90)
               data.append(chr(v))
           return  ''.join(data)
       
       print(get_random_code())
  • 高级

    • map() :

       # v = [11,22,33,44] 将v每个数据+100
       map(x,v) 
       # 第一个参数必须是一个函数
       # 第二个参数必须可迭代(可被for循环)

       

    • filter() :

       
      v = [11,22,44,55,'aa']
       def func(x):
           if type(s)==int:
               return True
           return False
       result = filter(func,v)
       print(list(result))
       ​
       # lambda:
       v = [11,22,44,55,'aa']
       result = filter(lambda x:type(x) == int,v)
       print(list(result))
      View Code

       

    • reduce() :

      python2在,python3被从内置中移除。

       import functools
       v = [11,22,44]
       result = functools.reduce(lambda a,b:a+b,v)
       print(result)
      View Code

       

  • 其他

    • type()

    • len()

    • id()

    • range()

    • open()

 
 # 1字节等于8位
 # IP:192.168.17.151  ->  01010101. 00101010 . 00101011 . 00101011
# 1.请将ip = "192.168.17.151"中的每个十进制数转换成二进制并通过,连接起来生成一个新的字符串
 ip = "192.168.17.151"
 ip_list = ip.split('.') # ['192','168','17','151']
 result = []
 for item in ip_list:
     result.append(bin(int(item)))
 print(','.join(result))
 ​
 # 2.请将ip= "192.168.17.151"中的每个十进制数转换成二进制:
 # 0010101010101010010101010 -> 十进制的值
View Code

 

 

5.6 md5加密

 
def get_md5(data):
     return hashlib.md5().update(data.encode('utf-8')).hexdigest()

 

虽然MD5不可逆,但是为了防止撞库破解,可以加盐

 def get_md5(data):
     return hashlib.md5('salt').update(data.encode('utf-8')).hexdigest()

 

ps : 盐越长破解越难

 # 应用场景: 登录注册加盐加密
 import hashlib
 ​
 USER_LIST= []
 ​
 def get_md5(data):
     obj = hashlib.md5()
     obj.update(data.encode('utf-8'))
     return obj.hexdigest()
 ​
 def register():
     print('**********用户注册**********')
     while True:
         user = input('请输入用户名:')
         if user =='N':
             return
         pwd = input('请输入密码:')
         temp = {'username':user,'password':get_md5(pwd)}
         USER_LIST.append(temp)
 ​
 def login():
     print('**********用户登录**********')
     user = input('请输入用户名:')
     pwd = input('请输入密码:')
 ​
     for item in USER_LIST:
         if item['username'] == user and item['password']== get_md5(pwd):
             return True
 ​
 register()
 print(USER_LIST)
 result = login()
 if result:
     print('登录成功')
 else:
     print('登录失败')
 ​
 # import getpass 模块作用: 终端输入密码不显示
View Code

 

 

5.7 装饰器

在不改变原来代码的前提下,在函数执行之前之后做操作。

 
import time
 ​
 # 计算函数执行时间
 # 装饰器的编写
 def get_time(arg):
     def inner():
         start_time = time.time() # 执行之前
         v = arg()
         end_time = time.time() # 执行之后之间
         print(end_time - start_time) # 计时
         return v
     return inner
 ​
 @get_time # 装饰器的应用
 def func():
     time.sleep(2) # 睡一下,执行时间
     print(123)
 ​
 func()
View Code

 

对于要装饰有参数的函数,装饰器可以这样 写:

 

5.8 推导式

5.8.1 列表推导式
 # 格式
 vals = [i for i in 'alex']
 # 变量 = [for循环的变量 for循环一个可迭代对象]
# 例子
 v1 = [i+100 for i in range(10)] # [100,101,....]
# 面试题
 def num():
     return [lambda x:i*x for i in range(4)]
 # num() -> [函数,函数,函数,函数]
 print([m(2) for m in num()]) # [6, 6, 6, 6]
 # 完整的格式
 v = [i for i in 可跌代对象]
 v = [i for i in 可跌代对象 if 条件] # 可筛选
View Code

 

5.8.2 集合推导式
 v = {i for i in 'alex'}

 

5.8.3 字典推导式
 v = {'k'+str(i):i for i  in range(10)}

 

 

第六章 模块

第七章 面向对象

第八章 网络编程

第九章 并发编程

第十章 数据库

第十一章 前端开发

第十二章 Django框架

第十三章 博客系统

第十四章 权限管理

第十五章 CRM客户关系管理软件

第十六章 restful-framework框架

第十七章 前端框架VUE

第十八章 Django+vue视频网站项目

第十九章 算法与设计模式

第二十章 web环境部署和上线流程

附录

常见错误

1.缩进错误

2.索引错误

3.函数参数个数异常

少了

多了

 

 

 

闭包