day18 总结

PYTHON学习笔记

第一章 计算机基础

1.1 硬件

计算机由CPU,主板,硬盘,内存,显卡,网卡等构成,硬件之间无法自行沟通联系

1.2 操作系统

操作系统用来控制硬件的工作,常见的操作系统有如下几种:

···Windows (XP/7/8/10/SERVER)

···Linux (centOS/ubantu/red hat)

···Mac

1.3 解释器和编译器

编程语言的开发者写出来的一种工具,将用户写的代码转换为二进制代码的010101交给操作系统去执行。

···解释型和编译型语言

···解释型语言 将代码一行一行交给电脑去处理,类似于同声翻译,python、PHP、ruby等

···编译型语言 将代码一次性完整的编译完成,生成一个新文件,将新文件交给电脑去执行,类似于说完之后整体翻译,C、C++、C#、JAVA、Go等

1.4 软件(应用程序)

电脑上的工具,类似于 记事本、图片查看、游戏等

1.5 进制

计算机的所有存储都只能依托于二进制的0和1,例如 电脑上储存的图片、音频、视频都是二进制,QQ微信发送的聊天信息也都是二进制。

···二进制 计算机内部识别

···八进制 现在很少用到

···十进制 人类识别

···十六进制 多数用来表示二进制,其表示的更短更节省资源 起始位置为 \x

二进制八进制十进制十六进制
0000 0 0 0
0001 1 1 1
0010 2 2 2
0011 3 3 3
0100 4 4 4
0101 5 5 5
0110 6 6 6
0111 7 7 7
1000 10 8 8
1001 11 9 9
1010 12 10 A
1011 13 11 B
1100 14 12 C
1101 15 13 D
1110 16 14 E
1111 17 15 F

 

第二章 Python入门

2.1 环境的安装

···解释器 Python3

为了使解释器可以在终端中方便运行,可把解释器的路径添加进环境变量中

···开发工具 Pycharm

2.2 编码

···编码基础

2.2.1. ASCII

最初美国人发明的只有英文数字和字符的

2.2.2. Unicode

万国码 包含目前所有的文字 长度为4个字节 32位,中文通常只占3个字节,24位

2.2.3. utf-8

目前常用的编码,能有效压缩Unicode编码,

···如果要修改默认编码 则需在文件头加上如下命令:

  # -*- coding:utf-8 -*- 

···需要注意的是,文件使用什么类型的编码编写,就要用什么类型的编码打开。

2.3 变量

···变量是为了给一个值起一个别名,方便后期调用

···命名规范 只能存在字母、数字、_(下划线) 且 数字不能为首位,还需规避python中的固有名词

第三章 数据类型

3.1 整形 int

3.1.1 整形的长度

···python2.7 中存在 int 、long

···python3 中int包含了long

3.1.2 整除

···python2.7 中 除法只能保留整数

···除非在题头引入命令:

    from __future__ import division

 

···python3 中 除法可以保留小数

 

3.2 布尔值 bool

··· ’ ‘空字符串/str()、0/int()、空列表[]/list()、空元组(,)/tuple()、空字典{}/dict()、空集合set()、None的布尔值为False

3.3 字符串 str

··· 字符串是在python文件中最常见的,为不可变类型,在python内存中的编码格式为Unicode

··· 字符串方法

3.3.1 大写 upper

v1='alex'
v2=v1.upper()
print(v2) # 'ALEX'
v3=v1.isupper()
print(v3) # False 此为判断是否为大写

3.3.2 小写 lower

v1='ALEX'
v2=v1.lower()
print(v2) # 'alex'
v3=v1.islower()
print(v3) # False 此为判断是否为小写

3.3.3 判断是否为数字 isdecimal 优先 、 isdigit

v = '1'
# v = '二'
# v = '②'
v1 = v.isdigit()  # '1'-> True; '二'-> False; '②' --> True
v2 = v.isdecimal() # '1'-> True; '二'-> False; '②' --> False
v3 = v.isnumeric() # '1'-> True; '二'-> True; '②' --> True
print(v1,v2,v3)
# 以后推荐用 isdecimal 判断是否是 10进制的数。

3.3.4 去除两侧空白以及指定字符串 strip 、 lstrip、rstrip

v1='  erwr  '
v2=v1.strip()
print(v2) # 'erwr'
v3=v2.strip('r')
print(v3) # 'erw'

3.3.5 分割 split、rsplit

v1='fewef'
v2=v1.split('w')
print(v2) # ['fe','ef']

3.3.6 以什么开始或结束 starswith 、 endswith

v1='fasfdsa'
v2=v1.starswith('fa')
print(v2) # True
v3=v1.endswith('s')
print(v3) # False

3.3.7 字符串格式化 format

v1='alex'
v2=29
v3='我叫{},今年{}岁'.format(v1,v2)
print(v3) # '我叫alex,今年29岁'

3.3.8 替换 replace

v1='abcd'
v2=v1.replace('ab','大傻')
print(v2) # '大傻cd'

3.3.9 编码和解码 encode 、 decode

v1='你好'
v2=v1.encode('utf-8')
print(v2) # b'\xe4\xbd\xa0\xe5\xa5\xbd' 转换成为二进制
v3=v2.decode('utf-8')
print(v3) # '你好'

3.3.10 加入 join

v1='hello'
v2='_'.join(v1)
print(v2) # 'h_e_l_l_o'

3.4 列表 list

··· 列表为有序序列,为可变类型

3.4.1 增 append/insert

v1=[1,2,3,4]
v1.append(5) # 序列末尾增加
print(v1) # [1,2,3,4,5]
v1.insert(3,'你好') # 在第一个参数位置之前加入,使其变为这个参数位置
print(v1)

3.4.2 删 remove / pop / clear / del

v1=[1,2,3,4]
v1.remove(4) # 元素4
print(v1) # [1,2,3]
v2=v1.pop(0) # 索引位置0 有返回值
print(v1) # [2,3]
print(v2) # 1 被删掉的元素
del v1[1] # 索引位置1
print(v1) # [2]
v1.clear() # 清空
print(v1) # []

3.4.3 改 通过索引位置

v1=[1,2,3,4]
v1[2]='你好'
print(v1) # [1, 2, '你好', 4]

3.4.4 查 通过索引位置

v1=[1,2,3,4]
print(v1[2]) # 3

3.4.5 强制转换 list

v1 = list("asdfadfasfdadfasfd")
print(v1) # ['a', 's', 'd', 'f', 'a', 'd', 'f', 'a', 's', 'f', 'd', 'a', 'd', 'f', 'a', 's', 'f', 'd']
v1 = list( (11,22,33,44,) )
print(v1) # [11, 22, 33, 44]

3.4.6 排序 sort

v1=[2,3,5,1]
v1.sort(reverse=False)
print(v1) # [1,2,3,5]
v1.sort(reverse=True)
print(v1) # [5,3,2,1]

3.4.7 反转/倒序 reverse

v1=[1,2,3,4]
v1.reverse()
print(v1) # [4,3,2,1]

3.5 元组 tuple

···元组为有序序列,不可变类型

3.5.1 无法增,删,改

3.5.2 查 通过索引位置

v1=(1,2,3,4)
print(v1[2]) # 3

3.5.3 强制转换 tuple

v1 = tuple("asdfadfasfdadfasfd")
print(v1) # ()'a', 's', 'd', 'f', 'a', 'd', 'f', 'a', 's', 'f', 'd', 'a', 'd', 'f', 'a', 's', 'f', 'd')
v1 = tuple( [11,22,33,44] )
print(v1) # (11, 22, 33, 44)

3.6 字典 dict

··· 字典为无序序列,为可变类型,列表/字典/集合 -> 不能放在集合中+不能作为字典的key

3.6.1 增、改 通过键值对 有则更改,无则新建、update

v1={'name':'alex','age':19}
v1['name']='王二'
print(v1) # {'name':'王二','age':19}
v1['gender']='男'
print(v1) # {'name':'王二','age':19,'gender':'男'}
v1.update({'name':'王麻子','智商':'无'})
print(v1) # {'name': '王麻子', 'age': 19, 'gender': '男', '智商': '无'}

3.6.2 删 del

v1={'name':'王二','age':19,'gender':'男'}
del v1['gender']
print(v1) # {'name':'王二','age':19}

3.6.3 查 通过键值对查询 、 get

v1={'name':'王二','age':19,'gender':'男'}
print(v1['name']) # '王二'
print(v1.get('name',666)) # '王二'   若有此键,返回对应的值
print(v1.get('alex',666)) # 666  若无此键,返回第二个参数

3.6.4 取出所有的键、值、键值对

v1={'name':'王二','age':19,'gender':'男'}
v2=v1.keys()
v3=v1.values()
v4=v1.items()
print(v2) # ['name','age','gender']
print(v3) # ['王二', 19, '男']
print(v4) # [('name', '王二'), ('age', 19), ('gender', '男')]

3.7 集合 set

··· 集合为无序序列,为可变类型,集合内的值唯一,列表/字典/集合 -> 不能放在集合中+不能作为字典的key

3.7.1 增 add

v1={1,2,3,4}
v1.add(555)
print(v1) # {1,2,3,4,555}

3.7.2 删 discard

v1={1,2,3,4}
v1.discard(2) # 元素
print(v1) # {1,3,4}

3.7.3 批量添加 update

v1={1,2,3,4}
v1.update({4,5,6,7})
print(v1) # {1, 2, 3, 4, 5, 6, 7} 去重,添加

3.7.4 交集 intersection

v1={1,2,3,4}
v2={4,5,6}
v3=v1.intersection(v2)
print(v3) # {4}

3.7.5 并集 union

v1={1,2,3,4}
v2={4,5,6}
v3=v1.union(v2)
print(v3) # {1, 2, 3, 4, 5, 6}

3.7.6 差集 difference

v1={1,2,3,4}
v2={4,5,6}
v3=v1.difference(v2) # v1有,v2没有的
print(v3) # {1, 2, 3}
v4=v2.difference(v1) # v2有,v1没有的
print(v4) # {5, 6}

3.7.7 对称差集 symmetric_difference

v1={1,2,3,4}
v2={4,5,6}
v3=v1.symmetric_difference(v2)
print(v3) # {1, 2, 3, 5, 6}

3.8 公共功能

3.8.1 索引 str/list/tuple/dict(键)

3.8.2 切片 str/list/tuple

3.8.3 步长 str/list/tuple/range

3.8.4 for循环 str/list/tuple/dict(键)/set

3.8.5 len计算长度 str/list/tuple/dict(键)/set

3.9 嵌套

3.10 数据类型的返回值问题

3.10.1 无返回值

v=[1,2,3,4,5]
v.apped(6)  # 无返回值 增加元素

3.10.2 仅有返回值,不修改原数据

v='alex'
v1=v.split('l') # 有返回值

v={'name':'alex','age':19}
v1=v.get('name',666) # 有返回值
v2=v.keys() # 有返回值

3.10.3 有返回值,也修改数据

v=[1,2,3,4]
v1=v.pop(0) # 有返回值,并且修改数据

3.10.4 常用如下

·str
	strip,返回字符串
	split,返回列表
	replace,返回字符串
	join,返回字符串。
·list
	append,无返回值,仅修改元素内部
	insert,无返回值,仅修改元素内部
	pop,返回要删除的数据
	remove,无返回值,仅修改元素内部
	find/index,返回索引的位置。
·dict
	get 返回键对应的值
	keys 返回列表
	values 返回列表
	items 返回列表

第四章 文件操作

4.1 文件基本操作

···把大象放进冰箱需要几步? 打开,操作 ,关闭

file=open('路径',mode='读、写、追加',encoding='编码格式')
file.read()
file.write()
file.close

4.2 打开模式

4.2.1 r 只读 w 只写 a 只追加

4.2.2 r+ 读和写 w+ 写和读(清空先) a+ 写和读

4.2.3 rb 二进制只读 wb 二进制只写 ab 二进制只追加

4.2.4 r+b 二进制读和写 w+b 二进制写和读(清空先) a+b 二进制写和读

4.3 操作

4.3.1 read() 全部读取到内存

4.3.2 read(1)

···表示一个字符

obj = open('a.txt',mode='r',encoding='utf-8')
data = obj.read(1) # 1个字符
obj.close()
print(data)

···表示一个字节

obj = open('a.txt',mode='rb')
data = obj.read(3) # 1个字节
obj.close()

4.3.3 write()

···字符串

obj = open('a.txt',mode='w',encoding='utf-8')
data = obj.write() 
obj.close()

···二进制

obj = open('a.txt',mode='wb')
info='ddddd'.encode('utf-8')
data = obj.write(info) 
obj.close()

4.3.4 seek() 光标所在的字节位置

obj = open('a.txt',mode='r',encoding='utf-8')
obj.seek(3) # 跳转到指定字节位置
data = obj.read()
obj.close()

print(data)




obj = open('a.txt',mode='rb')
obj.seek(3) # 跳转到指定字节位置
data = obj.read()
obj.close()

print(data)

4.3.5 tell() 获取当前光标的位置

obj = open('a.txt',mode='rb')
# obj.seek(3) # 跳转到指定字节位置
obj.read()
data = obj.tell()
print(data)
obj.close()

4.3.6 flush() 强制将内存中的数据写入到硬盘,在不关闭的状态下

v = open('a.txt',mode='a',encoding='utf-8')
while True:
    val = input('请输入:')
    v.write(val)
    v.flush()

v.close()

4.4 关闭文件

with open ('a.txt',mode='r',encoding='utf-8') as file:
    file.read() # # 缩进中的代码执行完毕后,自动关闭文件

4.5文件内容修改

with open('a.txt',mode='r',encoding='utf-8') as f1:
    data = f1.read()
new_data = data.replace('飞洒','666')

with open('a.txt',mode='w',encoding='utf-8') as f1:
    data = f1.write(new_data)
f1 = open('a.txt',mode='r',encoding='utf-8')
f2 = open('b.txt',mode='w',encoding='utf-8')

for line in f1:
    new_line = line.replace('阿斯','死啊')
    f2.write(new_line)
f1.close()
f2.close()
with open('a.txt',mode='r',encoding='utf-8') as f1, open('c.txt',mode='w',encoding='utf-8') as f2:
    for line in f1:
        new_line = line.replace('阿斯', '死啊')
        f2.write(new_line)

第五章 函数

5.1 发送邮件

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

msg = MIMEText('正文内容', 'plain', 'utf-8')
msg['From'] = formataddr(["发件人", '发件地址'])
msg['To'] = formataddr(["收件人", '收件地址'])
msg['Subject'] = "主题"

server = smtplib.SMTP("发件方服务器", 25)
server.login("发件邮箱", "密码")
server.sendmail('发件邮箱', ['收件邮箱', ], msg.as_string())
server.quit()

5.2 函数的基本结构

··· 本质:将N行代码拿到别处并给他起个名字,以后通过名字就可以找到这段代码并执行。

··· 场景:

  • 代码重复执行。

  • 代码量特别多超过一屏,可以选择通过函数进行代码的分割。

    # 函数的定义
    def 函数名():
        # 函数内容
        pass
    
    # 函数的执行
    函数名()
def func():
    pass

func() # 注意:函数如果不被调用,则内部代码永远不会被执行。

5.3 函数的参数

··· 函数的参数 优先位置参数,再关键字参数,实际参数可以是任意类型。

··· 任意类型 任意个数

··· 函数内部的数据是否会混乱。

  • 函数内部执行相互之间不会混乱

  • 执行完毕 + 内部元素不被其他人使用 => 销毁

# 位置传参

def func(a,b): # a为形式参数
    pass

func(c,d) # b为实际参数

# 关键字传参

def func(a1, a2):
    print(a1, a2)

func(a2=99,a1=2)

# 关键字传参数和位置传参可以混合使用(位置传入的参数 > 关键字参数在后 = 总参数个数)
def func1(a1, a2, a3):
    print(a1, a2, a3)

# func(1, 2, a3=9)
# func(1, a2=2, a3=9)
# func(a1=1, a2=2, a3=9)
# func(a1=1, 2,3) # 错误

# 默认参数

def func(a1,a2,a3=9,a4=10):
    print(a1,a2,a3,a4)

func(11,22)
func(11,22,10)
func(11,22,10,100)
func(11,22,10,a4=100)
func(11,22,a3=10,a4=100)
func(11,a2=22,a3=10,a4=100)
func(a1=11,a2=22,a3=10,a4=100)
def send_email(to):
    template = "要给%s发送邮件" % (to,)
    print(template)

user_input = input('请输入角色:')

if user_input == '管理员':
    send_email('xxxx@qq.com')
elif user_input == '业务员':
    send_email('xxxxo@qq.com')
elif user_input == '老板':
    send_email('xoxox@qq.com')
万能参数(打散)

*args

可以接受任意个数的位置参数,并将参数转换成元组。

调用函数无 *

def func(*args):
    print(args)

func(1,2,3,4) # (1, 2, 3, 4)
调用函数有 *

def func(*args):
    print(args)

func(*(1,2,3,4)) # (1, 2, 3, 4)
func(*[1,2,3,4]) # (1, 2, 3, 4)
只能用位置传参

def func(*args):
    print(args)

# func(1)
# func(1,2)
func(1,2) # (1, 2) 
func((11,22,33,44,55)) # ((11,22,33,44,55),) 元组为一个元素
func(*(11,22,33,44,55)) # (11,22,33,44,55) 打散

**kwargs
可以接受任意个数的关键字参数,并将参数转换成字典。

调用函数无 **

def func(**kwargs):
    print(kwargs)

func(k1=1,k2="alex") # {'k1': 1, 'k2': 'alex'}
调用函数有**

def func(**kwargs):
    print(kwargs)
func(**{'k1':'v2','k2':'v2'}) # {'k1':'v2','k2':'v2'}
只能用关键字传参

综合应用:无敌 + 无敌 => 真无敌

def func(*args,**kwargs):
    print(args,kwargs)

# func(1,2,3,4,5,k1=2,k5=9,k19=999)
func(*[1,2,3],k1=2,k5=9,k19=999) # (1, 2, 3) {'k1': 2, 'k5': 9, 'k19': 999}
func(*[1,2,3],**{'k1':1,'k2':3}) # (1, 2, 3) {'k1': 1, 'k2': 3}
func(111,222,*[1,2,3],k11='alex',**{'k1':1,'k2':3}) # (111, 222, 1, 2, 3) {'k11': 'alex', 'k1': 1, 'k2': 3}

# def func(a1,*args,a2):   # args 代指所有位置参数  *args 可以代表一个整体的元组作为参数
#     print(a1,args,a2)
# func(1,2,3,1,3,a2=5)

# def func(a1,*args,a2=9):
#     print(a1,args,a2)
# func(1,2,3,1,3)

# def func(**kwargs):   # kwargs 代表所有的关键字参数  **kwargs 可以代表一个整体的字典作为参数
#     print(kwargs)
# func(**{'k1':'v2','k2':'v2'}) # kwargs={'k1':'v2','k2':'v2'}
#
# func(k1=1,k2="alex") # kwargs={'k1': 1, 'k2': 'alex'}
# func(k1={'k1':99,'k2':777},k2="alex") # kwargs={'k1': {'k1': 99, 'k2': 777}, 'k2': 'alex'}
# func(**{'k1':'v2','k2':'v2'}) # kwargs={'k1':'v2','k2':'v2'}

慎用可变类型作为函数的参数

# 如果要想给value设置默认是空列表

# 不推荐(坑)
def func(data,value=[]): 
    pass 

# 推荐
def func(data,value=None):
    if not value:
        value = []
def func(data,value=[]): 
    value.append(data)
    return value 

v1 = func(1) # [1,]
v2 = func(1,[11,22,33]) # [11,22,33,1]
def func(a,b=[]):
    b.append(a)
    return b

l1 = func(1)
l2 = func(2,[11,22])
l3 = func(3)

# [1,3]   [11,22,2]   [1,3]
print(l1,l2,l3)
def func(a,b=[]):
    b.append(a)
    print(b)
    
func(1)
func(2,[11,22,33])
func(3)

# [1]  [11,22,33,2]   [1,3]

5.4 函数的返回值

··· 函数没有返回值,默认返回:None

··· 函数内部执行过程中遇到return,就终止。

def func():
    return xxx

v=func()  #  v 即为 返回值 需要变量接收
def func1():
    return "完成" # 函数每次执行到此,就返回;所以下面代码永远不执行。
    for i in range(10):
        print(i)
func1()

def func2():
    for i in range(10):
        print(i)
        return "完成"
    print(666)
func2()
def func():
    return (1,2,3)

v = func()
print(v)

# 特殊:返回元组
def func():
    return 5,8,"alex"

v = func()
print(v) # (5, 8, 'alex')

5.5 函数的作用域

python中:

  • py文件:全局作用域

  • 函数:局部作用域

    a = 1
    def s1():
        x1 = 666
        print(x1)
        print(a)
        print(b)
    
    b = 2
    print(a)
    s1()
    
    a = 88888
    def s2():
        print(a,b)
        s1()
    
    s2()
  • 总结:

    • 一个函数是一个作用域

      def func():
          x = 9
          print(x)
      func()
      print(x)
    • 作用域中查找数据规则:优先在自己的作用域找数据,自己没有就去 "父级" -> "父级" -> 直到全局,全部么有就报错。注意:父级作用域中的值到底是什么?

      x = 10
      def func():
          x = 9
          print(x)
      
      func()

      子作用域中只能 找到父级中的值 ,默认无法重新为父级的变量进行赋值。(global/nonlocal可以强制做)

      # #####################
      name = 'oldboy'
      def func():
          name = 'alex' # 在自己作用域再创建一个这样的值。
          print(name)
      func()
      print(name)
      
      
      
      # #####################
      name = [1,2,43]
      def func():
          name.append(999)
          print(name)
      func()
      print(name)
      
      # ###################### 如果非要对全局的变量进行赋值
      # 示例一
      name = ["老男孩",'alex']
      def func():
          global name
          name = '我'
      func()
      print(name) # 我
      # 示例一
      name = "老男孩"
      def func():
          name = 'alex'
          def inner():
              global name
              name = 999
          inner()
          print(name)
      func() # alex
      print(name) # 999
      
      
      name = "老男孩"
      def func():
          name = 'alex'
          def inner():
              global name
              name = 999
          inner()
          print(name)
      func() # alex
      print(name) # 999
      
      # ############################## nonlocal
      name = "老男孩"
      def func():
          name = 'alex'
          def inner():
              nonlocal name # 找到上一级的name
              name = 999
          inner()
          print(name)
      func() # 999
      print(name) # 老男孩

5.6 函数作为变量

def func():
    print(123)

v1=func
v1() # 123

# 易于混淆:
def func():
    return 123

func_list1 = [func,func,func]
func_list2 = [func(),func(),func()]

print(func_list1) # ['内存地址','内存地址','内存地址'] 未加括号未调用
print(func_list2) # [123,123,123] 加了括号才调用

info = {
    'k1':func,
    'k2':func(),
}

print(info)

5.7 函数作为参数---高阶函数

def func(a):   
    print(a)
    
func(1) # 1
func([1,2,3,4]) # [1,2,3,4] # 变量可以是任何类型

def show():   
    return 999

func(show) # show函数的内存地址   如果函数没有写出返回值,那么返回值为None
def func(arg):
    v1 = arg()
    print(v1)
    
def show():
    print(666)
    
func(show) # 666 None   show 打印了666,返回值None,传入参数None给func,v1=None
def func(arg):
    v1 = arg()
    print(v1)
    
def show():
    print(666)
    
result = func(show)
print(result)   # 666 None None  首先按照顺序 先调用show,打印666,返回None,传入func,V1=None,打印V1,返回None,最终再打印None

5.8 函数作为返回值---高阶函数

def func():
    print(123)

def bar():
    return func

v = bar()

v() # 123
name = 'oldboy'
def func():
    print(name)
    
def bar():
    return func

v = bar()
v() # oldboy

def bar():
    def inner():
        print(123)
    return inner

v = bar()
v() # 123

name = 'oldboy'
def bar():
    name = 'alex'
    def inner():
        print(name)
    return inner
v = bar()
v() # alex

name = 'oldboy'
def bar(name):
    def inner():
        print(name)
    return inner
v1 = bar('alex') # { name=alex, inner }  # 闭包,为函数创建一块区域(内部变量供自己使用),为他以后执行提供数据。
v2 = bar('eric') # { name=eric, inner }
v1() # alex
v2() # eric

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
info[1]() # 1
info[4]() # 4

5.9 闭包

  • 函数执行的流程分析(函数到底是谁创建的?)

  • 闭包概念:为函数创建一块区域并为其维护自己数据,以后执行时方便调用。【应用场景:装饰器 / SQLAlchemy源码】

def func(name):
    def inner():
        print(name)
	return inner 

v1 = func('alex')
v1() # alex
v2 = func('eric')
v2() # eric
# 不是闭包
def func1(name):
    def inner():
        return 123
    return inner 

# 是闭包:封装值 + 内层函数需要使用。
def func2(name):
    def inner():
        print(name)
        return 123
    return inner 

5.10 lambda 表达式

func = lambda 参数(若有): 函数体  (默认返回值赋值给函数名func,可以理解为func是一个变量)
# lambda表达式用来表示简单的函数,函数体只能有一行。

# 三元运算,为了解决简单的if else的情况,如:
if 1 == 1:
    a = 123
else:
    a = 456

a =  123  if 1 == 1 else 456

# lambda表达式,为了解决简单函数的情况,如:
def func(a1,a2):
    return a1 + 100 

func = lambda a1,a2: a1+100
# 一些示例
func1 = lambda : 100 

func2 = lambda x1: x1 * 10

func3 = lambda *args,**kwargs: len(args) + len(kwargs)

DATA = 100
func4 = lambda a1: a1 + DATA
v = func4(1)
print(v) # 101

DATA = 100
def func():
    DATA = 1000
    func4 = lambda a1: a1 + DATA
    v = func4(1)
    print(v) 
func() # 1001

func5 = lambda n1,n2: n1 if n1 > n2 else n2
v = func5(1111,2)
print(v) # 1111

5.11 内置函数

5.11.1 其他类

len() 计算长度
open() 打开文件
range() 产生序列
id() 查看内存地址
type() 查看类型

5.11.2 输入输出类

input() 输入
print() 输出

5.11.3 强制转换类

str()
int()
bool()
list()
tuple()
dict()
set()

5.11.4 数学相关

abs() 绝对值
v=abs(1)
print(v) # 1
v=abs(-1)
print(v) # 1
float() 转换为浮点数
v=55
v1=float(v)
print(v1) # 55.0

v=55.5
v1=int(v)
print(v1) # 55
max / min 最大值或最小值
v=[1,2,3,4]
v1=max(v)
v2=min(v)
print(v1) # 4
print(v2) # 1
sum() 求和
v=[1,2,3,4]
v1=sum(v)
print(v1) # 10
divmod() 求商和余数
a,b=divmod(101,5)
print(a,b) # (20,1)

# 练习题  请通过分页对数据进行展示
"""
要求:
    每页显示10条数据
    让用户输入要查看的页面:页码
"""

USER_LIST = []
for i in range(1,836):
    temp = {'name':'你少妻-%s' %i,'email':'123%s@qq.com' %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('要查看第几页:'))
    if pager < 1 or pager > max_page_num:
        print('页码不合法,必须是 1 ~ %s' %max_page_num )
    else:
        """
        # 第1页:USER_LIST[0:10] -> 0123456789
        # 第2页:USER_LIST[10:20]
        # 第3页:USER_LIST[20:30]
        ...
        """
        start = (pager-1) * per_page_count
        end = pager * per_page_count
        data = USER_LIST[start:end]
        for item in data:
            print(item)

5.11.5 进制转换相关

bin() 将十进制转换为二进制
a=23
b=bin(a)
print(b)
oct() 将十进制转换为八进制
a=23
b=oct(a)
print(b)
int() 将其他进制转换为十进制
# 二进制转化成十进制
v1 = '0b1101'
result = int(v1,base=2)
print(result)

# 八进制转化成十进制
v1 = '0o1101'
result = int(v1,base=8)
print(result)

# 十六进制转化成十进制
v1 = '0x1101'
result = int(v1,base=16)
print(result)
hex() 将十进制转换为十六进制
a=23
b=hex(a)
print(b)
# 1字节等于8位
# IP: 192.168.12.79  ->  001010010 . 001010010 . 001010010 . 001010010

# 1. 请将 ip = "192.168.12.79" 中的每个十进制数转换成二进制并通过,连接起来生成一个新的字符串。
ip = "192.168.12.79"
ip_list = ip.split('.') # ['192','168','12','79']
result = []
for item in ip_list:
    result.append(bin(int(item)))
print(','.join(result))


# 2. 请将 ip = "192.168.12.79" 中的每个十进制数转换成二进制: 
#          0010100100001010010001010010001010010 -> 十进制的值。

info='192.168.12.79'
fina='0b'
# 通过'.'分割
info_split=info.split('.')
# 通过遍历列表得到列表中每一个元素
for i in info_split:
    # 将字符串转为整形再转为二进制,
    bin_num=bin(int(i))
    # 将二进制去除0b
    str_num=bin_num[2:]
    # 凑齐八位
    if len(str_num) < 8:
        str_num=(8-len(str_num))*'0'+str_num
    # 链接所有的字符串
    fina+=str_num
print(int(fina,base=2))

# 3232238671

5.11.6 编码相关

chr,将十进制数字转换成 unicode 编码中的对应字符串。(unicode编码对照表)
v = chr(99)
print(v) # c
ord,根据字符在unicode编码中找到其对应的十进制。
num = ord('中')
print(num) # 20013
随机验证码
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)


code = get_random_code()
print(code)
import random # 导入一个模块 

v = random.randint(起始,终止) # 得到一个机数 高级一些的内置函数

5.11.7 高级一点的函数

map

循环每个元素(第二个参数),然后让每个元素执行函数(第一个参数),将每个函数执行的结果保存到新的列表中,并返回。

v1 = [11,22,33,44]
result = map(lambda x:x+100,v1)
print(list(result)) # 特殊 [111, 122, 133, 144]
filter

循环每个元素(第二个参数),然后让每个元素执行函数(第一个参数),将函数执行的结果筛选后保存到新的列表中,并返回。

v1 = [11,22,33,'asd',44,'xf']

def func(x):
    if type(x) == int:
        return True
    return False
result = filter(func,v1) # [11,]
print(list(result)) # [11, 22, 33, 44]


result = filter(lambda x: True if type(x) == int else False ,v1)
print(list(result))

result = filter(lambda x: type(x) == int ,v1)
print(list(result))
reduce

循环每个元素(第二个参数),然后让每个元素执行函数(第一个参数),将函数执行的结果做统计后返回。

import functools
v1 = ['wo','hao','e']

def func(x,y):
    return x+y
result = functools.reduce(func,v1) 
print(result)

result = functools.reduce(lambda x,y:x+y,v1)
print(result)

5.12 装饰器

在不改变原函数内部代码的基础上,在函数执行之前和之后自动执行某个功能

5.12.1 装饰器

def func():
    def inner():
        pass
    return inner 

v = func()
print(v) # inner函数
# #########################################
def func(arg):
    def inner():
        print(arg)
    return inner 

v1 = func(1) # inner
v2 = func(2) # inner
# #########################################
def func(arg):
    def inner():
        arg()
    return inner

def f1():
    print(123)

v1 = func(f1)
v1() # 123
# ###########################################
def func(arg):
    def inner():
        arg()
    return inner

def f1():
    print(123)
    return 666

v1 = func(f1)
result = v1() # 执行inner函数 / f1含函数 -> 123 
print(result) # None
# ###########################################
def func(arg):
    def inner():
        return arg()
    return inner

def f1():
    print(123)
    return 666

v1 = func(f1)
result = v1() # 执行inner函数 / f1含函数 -> 123
print(result) # 666
# ###########################
def func():
    print(1)
    
v1 = func
func = 666
# 示例
def func(arg):
    def inner():
        print('before')
        v = arg()
        print('after')
        return v 
    return inner 

def index():
    print('123')
    return '666'


# 示例一
"""
v1 = index() # 执行index函数,打印123并返回666赋值给v1.
"""
# 示例二
"""
v2 = func(index) # v2是inner函数,arg=index函数
index = 666 
v3 = v2()
"""
# 示例三
"""
v4 = func(index)
index = v4  # index ==> inner 
index()
"""

# 示例四
index = func(index)
index()
# 用法!!

def func(arg):
    def inner():
        v = arg()
        return v 
    return inner 

# 第一步:执行func函数并将下面的函数参数传递,相当于:func(index)
# 第二步:将func的返回值重新赋值给下面的函数名。 index = func(index)
@func 
def index():
    print(123)
    return 666

print(index) # 内存地址
# 课上示例

# 计算函数执行时间

def wrapper(func):
    def inner():
        start_time = time.time()
        v = func()
        end_time = time.time()
        print(end_time-start_time)
        return v
    return inner

@wrapper
def func1():
    time.sleep(2)
    print(123)
@wrapper
def func2():
    time.sleep(1)
    print(123)

def func3():
    time.sleep(1.5)
    print(123)

func1()
# 编写装饰器

# 装饰器的编写
def x(func):
    def y():
        # 前
        ret = func()
        # 后
        return ret 
   	return y 

# 装饰器的应用
@x
def index():
    return 10

@x
def manage():
    pass

# 执行函数,自动触发装饰器了
v = index()
print(v) # 10
# 装饰器	编写格式

def 外层函数(参数): 
    def 内层函数(*args,**kwargs):
        return 参数(*args,**kwargs)
    return 内层函数


# 装饰器   应用格式

@外层函数
def index():
    pass

index()

5.12.2 带参数的装饰器

5.12.2.1 装饰器标准
def func(index):
    def inner(*args,**kwargs):
        return index(*args,**kwargs)
    return inner

@func
def index():
    pass

index()
5.12.2.2 参数
def x(func):
    def inner(a1):
        return func(a1)
    return inner 

@x
def index(a1):
	pass
def x(func):
    def inner(a1,a2):
        return func(a1,a2)
    return inner 

@x
def index(a1,a2):
	pass

# index = inner
index(1,2)
# ################################### 参数统一的目的是为了给原来的index函数传参
def x(func):
    def inner(a1,a2):
        return func()
    return inner 

@x
def index():
	pass
# func = 原来的index函数
# index = inner
index(1,2)
def x1(func):
    def inner(*args,**kwargs):
        return func(*args,**kwargs)
    return inner 

@x1
def f1():
    pass

@x1
def f2(a1):
    pass
@x1
def f3(a1,a2):
    pass 
5.12.2.3 返回值
def x1(func):
    def inner(*args,**kwargs):
        data = func(*args,**kwargs)
        return data
    return inner 

@x1
def f1():
    print(123)
    
v1 = f1() # 123
print(v1) # None
def x1(func):
    def inner(*args,**kwargs):
        data = func(*args,**kwargs)
        return data
    return inner 

@x1
def f1():
    print(123)
    return 666
v1 = f1() # 123
print(v1) # 666
def x1(func):
    def inner(*args,**kwargs):
        data = func(*args,**kwargs)
    return inner 

@x1
def f1():
    print(123)
    return 666

v1 = f1() # 123
print(v1) # None
装饰器建议写法:
def x1(func):
    def inner(*args,**kwargs):
        data = func(*args,**kwargs)
        return data
    return inner 
5.12.2.4 关于前后
def x1(func):
    def inner(*args,**kwargs):
        print('调用原函数之前')
        data = func(*args,**kwargs) # 执行原函数并获取返回值
        print('调用员函数之后')
        return data
    return inner 

@x1
def index():
    print(123)
    
index()
5.12.2.5 带参数的装饰器
# 第一步:执行 ret = xxx(index)
# 第二步:将返回值赋值给 index = ret 
@xxx
def index():
    pass

# 第一步:执行 v1 = uuu(9)
# 第二步:ret = v1(index)
# 第三步:index = ret 
@uuu(9)
def index():
    pass
# ################## 普通装饰器 #####################
def wrapper(func):
    def inner(*args,**kwargs):
        print('调用原函数之前')
        data = func(*args,**kwargs) # 执行原函数并获取返回值
        print('调用员函数之后')
        return data
    return inner 

@wrapper
def index():
    pass

# ################## 带参数装饰器 #####################
def x(counter):
    def wrapper(func):
        def inner(*args,**kwargs):
            data = func(*args,**kwargs) # 执行原函数并获取返回值
            return data
        return inner 
	return wrapper 

@x(9)
def index():
    pass
# 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,把每次结果添加到列表中,最终返回列表。
def xxx(counter):
    print('x函数')
    def wrapper(func):
        print('wrapper函数')
        def inner(*args,**kwargs):
            v = []
            for i in range(counter):
                data = func(*args,**kwargs) # 执行原函数并获取返回值
                v.append(data)
            return v
        return inner
    return wrapper

@xxx(5)
def index():
    return 8

v = index()
print(v)

# 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,并返回最后一次执行的结果【面试题】
def xxx(counter):
    print('x函数')
    def wrapper(func):
        print('wrapper函数')
        def inner(*args,**kwargs):
            for i in range(counter):
                data = func(*args,**kwargs) # 执行原函数并获取返回值
            return data
        return inner
    return wrapper

@xxx(5)
def index():
    return 8

v = index()
print(v)
# 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,并返回执行结果中最大的值。
def xxx(counter):
    print('x函数')
    def wrapper(func):
        print('wrapper函数')
        def inner(*args,**kwargs):
            value = 0
            for i in range(counter):
                data = func(*args,**kwargs) # 执行原函数并获取返回值
                if data > value:
                    value = data 
            return value
        return inner
    return wrapper

@xxx(5)
def index():
    return 8

v = index()
print(v)
def x(counter):
    print('x函数')
    def wrapper(func):
        print('wrapper函数')
        def inner(*args,**kwargs):
            if counter:
                return 123
            return func(*args,**kwargs)
        return inner
    return wrapper

@x(True)
def fun990():
    pass

@x(False)
def func10():
    pass

5.13 推导式

5.13.1 列表推导式

"""
目的:方便的生成一个列表。
格式:
	v1 = [i for i in 可迭代对象 ]
	v2 = [i for i in 可迭代对象 if 条件 ] # 条件为true才进行append
"""
v1 = [ i for i in 'alex' ]  
v2 = [i+100 for i in range(10)]
v3 = [99 if i>5 else 66  for i in range(10)]

def func():
    return 100
v4 = [func for i in range(10)]

v5 = [lambda : 100 for i in range(10)]
result = v5[9]()

def func():
    return i
v6 = [func for i in range(10)]
result = v6[5]()

v7 = [lambda :i for i in range(10)]
result = v7[5]()


v8 = [lambda x:x*i for i in range(10)] # 新浪微博面试题
# 1.请问 v8 是什么?
# 2.请问 v8[0](2) 的结果是什么?

# 面试题
def num():
    return [lambda x:i*x for i in range(4)]
# num() -> [函数,函数,函数,函数]
print([ m(2) for m in num() ]) # [6,6,6,6]

# ##################### 筛选 #########################
v9 = [i for i in range(10) if i > 5]

5.13.2 集合推导式

v1 = { i for i in 'alex' }

5.13.3 字典推导式

v1 = { 'k'+str(i):i for i in range(10) }

5.14 函数递归

函数自己调用自己。(效率低)

def func():
    print(1)
    func()
    
func()
def func(i):
    print(i)
    func(i+1)
    
func(1)
def func(a,b):
    # 1
    # 1
    # 2
    # 3 
    # 5 
    print(b) 
    func(b,a+b)
    
func(0,1)
def func(a):
    if a == 5:
        return 100000
    result = func(a+1) + 10
    return result 

v = func(1)
# 递归的返回值
def func(a):
    if a == 5:
        return 100000
    result = func(a+1) + 10

v = func(1)

5.15 迭代器

5.15.1 迭代器

迭代器是对某种可迭代对象的每一个元素进行逐一获取,具有__next__()方法,且每次调用都会获取可迭代对象的一个元素(从前往后依次获取)

5.15.2 列表转成迭代器

v1=iter([1,2,3,4])
v1=[1,2,3,4].__iter__()    # 两者等值

5.15.3 迭代器获取值

反复调用__next__()方法

v1=[1,2,3,4]
# 列表转换成迭代器
v2=iter(v1)
result1 = v2.__next__()
print(result1)
result2 = v2.__next__()
print(result2)
result3 = v2.__next__()
print(result3)
result4 = v2.__next__()
print(result4)
result5 = v2.__next__()
print(result5)


v1='alex'
v2=iter(v1)
while True:
    try:
        result = v2.__next__()
        print(result)
    except exception as e:
        break	
  • 直到报错:StopIteration错误,表示已经迭代完毕。

  • 如何判别一个对象是否是迭代器:内部是否有__next__方法

5.15.4 for循环的底层原理就是迭代器

v1 = [11,22,33,44]

# 1.内部会将v1转换成迭代器
# 2.内部反复执行 迭代器.__next__()
# 3.取完不报错
for item in v1:
    print(item)

5.15.5 可迭代对象

··· 内部有__iter__()方法且返回一个迭代器

v1 = [11,22,33,44]
result = v1.__iter__()

··· 可以被for循环

5.16 生成器(函数的变异)

# 函数
def func():
    return 123
func()
# 生成器函数(内部是否包含yield)
def func():
    print('F1')
    yield 1
    print('F2')
    yield 2
    print('F3')
    yield 100
    print('F4')
# 函数内部代码不会执行,返回一个 生成器对象 。
v1 = func()
# 生成器是可以被for循环,一旦开始循环那么函数内部代码就会开始执行。
for item in v1:
    print(item) # F1 1 F2 2 F3 100 F4
def func():
    count = 1
    while True:
        yield count
        count += 1
        
val = func()

for item in val:
    print(item)

总结:函数中如果存在yield,那么该函数就是一个生成器函数,调用生成器函数会返回一个生成器,生成器只有被for循环时,生成器函数内部的代码才会执行,每次循环都会获取yield返回的值。

def func():
    count = 1
    while True:
        yield count
        count += 1
        if count == 100:
            return

val = func()
for item in val:
    print(item)

示例:读文件

def func():
    """
    分批去读取文件中的内容,将文件的内容返回给调用者。
    :return:
    """
    cursor = 0
    while True:
        f = open('db', 'r', encoding='utf-8')# 通过网络连接上redis
        # 代指   redis[0:10]
        f.seek(cursor)
        data_list =[]
        for i in range(10):
            line = f.readline()
            if not line:
                return
            data_list.append(line)
        cursor = f.tell()
        f.close()  # 关闭与redis的连接


        for row in data_list:
            yield row


for item in func():
    print(item)

总结 迭代器和生成器

  • 迭代器,对可迭代对象中的元素进行逐一获取,迭代器对象的内部都有一个 next方法,用于以一个个获取数据。

  • 可迭代对象,可以被for循环且此类对象中都有 iter方法且要返回一个迭代器(生成器)。

  • 生成器,函数内部有yield则就是生成器函数,调用函数则返回一个生成器,循环生成器时,则函数内部代码才会执行。

    特殊的迭代器(**):

    def func():
        yield 1
        yield 2
        yield 3
    
    v = func()
    result = v.__next__()
    print(result)
    result = v.__next__()
    print(result)
    result = v.__next__()
    print(result)
    result = v.__next__()
    print(result)

    特殊的可迭代对象:

    def func():
        yield 1
    
    v = func()
    result = v.__iter__()
    print(result)

第六章 模块

6.0 模块基本知识

6.0.1 内置模块

python内部提供的功能。

import sys
print(sys.argv)

6.0.2 第三方模块

下载/安装/使用

# 把pip.exe 所在的目录添加到环境变量中。

pip install 要安装的模块名称  # pip install xlrd
  • python36 -m pip install --upgrade pip

  • 安装完成后,如果导入不成功。

    • 重启pycharm。

    • 安装错了。

  • 源码安装:

    • 下载源码包:压缩文件。

    • 解压文件

    • 打开cmd窗口,并进入此目录:cd C:\Python36\Lib\site-packages

    • 执行:python36 setup.py build

    • 执行:python36 setup.py install

  • 安装路径:C:\Python36\Lib\site-packages

6.0.3 自定义模块

  • py文件

  • 文件夹 __init__.py

6.0.4 模块的调用

定义模块时可以把一个py文件或一个文件夹(包)当作一个模块,以方便于以后其他py文件的调用。

对于包的定义:

  • py2:文件见中必须有 _ _init _ _.py 。

  • py3:不需要 _ init _.py .

推荐大家以后写代码时,都要加上此文件。

# import 模块 模块.函数()
import requests
# from 模块 import 函数 函数() 【as起别名 / *】
from b4s import *
# from 模块 import 函数 as 别名 别名()
fron bs4 import BeautifulSoup as s
'''
lizohng
	- jd.py
    - pdd.py
    - tb.py
包.py
'''
import lizhong.jd
lizhong.jd.f1()

from lizhong import jd
jd.f1()

from lizhong.jd import f1
f1()

# 模块和要执行的py文件在同一目录 且 需要 模块中的很多功能时,推荐用: import 模块
# 其他推荐:from 模块 import 模块 模块.函数()
# 其他推荐:from 模块.模块 import 函数 函数()

6.1 hashlib ---将指定的 “字符串” 进行加密。

import hashlib

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

val = get_md5('123')
print(val)

# 加盐
import hashlib

def get_md5(data):
    obj = hashlib.md5("sidrsicxwersdfsaersdfsdfresdy54436jgfdsjdxff123ad".encode('utf-8'))
    obj.update(data.encode('utf-8'))
    result = obj.hexdigest()
    return result

val = get_md5('123')
print(val)

密码加密

import hashlib
USER_LIST = []
def get_md5(data):
    obj = hashlib.md5("12:;idrsicxwersdfsaersdfsdfresdy54436jgfdsjdxff123ad".encode('utf-8'))
    obj.update(data.encode('utf-8'))
    result = obj.hexdigest()
    return result


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()
result = login()
if result:
    print('登陆成功')
else:
    print('登陆失败')

密码不显示 (终端专属)

import getpass

pwd = getpass.getpass('请输入密码:')
if pwd == '123':
    print('输入正确')

6.2 sys---python解释器相关的数据

6.2.1 sys.getrefcount

获取一个值的应用计数

a = [11,22,33]
b = a
print(sys.getrefcount(a)) # 2   这儿各自

6.2.2 sys.getrecursionlimit

python默认支持的递归数量

6.2.3 sys.stdout.write

--> print (进度) 被print替代

import time
for i in range(1,101):
    msg = "%s%%\r" %i   # \r 回到本行最开始的位置
    print(msg,end='')
    time.sleep(0.05)
import os

# 1. 读取文件大小(字节)
file_size = os.stat('20190409_192149.mp4').st_size

# 2.一点一点的读取文件
read_size = 0
with open('20190409_192149.mp4',mode='rb') as f1,open('a.mp4',mode='wb') as f2:
    while read_size < file_size:
        chunk = f1.read(1024) # 每次最多去读取1024字节
        f2.write(chunk)
        read_size += len(chunk)
        val = int(read_size / file_size * 100)
        print('%s%%\r' %val ,end='')

6.2.4 sys.argv

python代码获取命令行参数

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
让用户执行脚本传入要删除的文件路径,在内部帮助用将目录删除。
C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test
C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py

"""
import sys

# 获取用户执行脚本时,传入的参数。
# C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test
# sys.argv = [D:/code/s21day14/7.模块传参.py, D:/test]
path = sys.argv[1]

# 删除目录
import shutil
shutil.rmtree(path)

6.2.5 sys.path

默认Python去导入模块时,会按照sys.path中的路径挨个查找

# import sys
# sys.path.append('D:\\')
# import oldboy

6.3 os---和操作系统相关的数据

6.3.1 os.path.exists(path)

如果path存在,返回True;如果path不存在,返回False # 确认路径是否存在

6.3.2 os.stat('XX.mp4').st_size

获取文件大小

6.3.3 os.path.abspath()

获取一个文件的绝对路径

path = '20190409_192149.mp4' # D:\code\s21day14\20190409_192149.mp4

import os
v1 = os.path.abspath(path)
print(v1)

6.3.4 os.path.dirname

获取路径的上级目录

import os
v = r"D:\code\s21day14\20190409_192149.mp4"

print(os.path.dirname(v))

6.3.5 os.path.join

路径的拼接

import os
path = "D:\code\s21day14" # user/index/inx/fasd/
v = 'n.txt'

result = os.path.join(path,v)
print(result)
result = os.path.join(path,'n1','n2','n3')
print(result)

6.3.6 os.listdir

查看一个目录下所有的文件【第一层】

import os

result = os.listdir(r'D:\code\s21day14')
for path in result:
    print(path)

6.3.7 os.walk

查看一个目录下所有的文件【所有层】

import os

result = os.walk(r'D:\code\s21day14')
for a,b,c in result:
    # a,正在查看的目录 b,此目录下的文件夹  c,此目录下的文件
    for item in c:
        path = os.path.join(a,item)
        print(path)

补充:转义

v1 = r"D:\code\s21day14\n1.mp4"  (推荐)
print(v1)


v2 = "D:\\code\\s21day14\\n1.mp4"
print(v2)

6.3.8 os.makedirs

创建目录和子目录

import os
file_path = r'db\xx\xo\xxxxx.txt'

file_folder = os.path.dirname(file_path)
if not os.path.exists(file_folder):
    os.makedirs(file_folder)

with open(file_path,mode='w',encoding='utf-8') as f:
    f.write('asdf')

6.3.9 os.rename

重命名

import os
os.rename('db','sb')

6.4 shutil

import shutil
shutil.rmtree(path) # 强制删除

6.5 json

6.5.1 dumps 和 loads

import json
# 序列化,将python的值转换为json格式的字符串。
# v = [12,3,4,{'k1':'v1'},True,'asdf']
# v1 = json.dumps(v)
# print(v1)

# 反序列化,将json格式的字符串转换成python的数据类型
# v2 = '["alex",123]'
# print(type(v2))
# v3 = json.loads(v2)
# print(v,type(v3))
# 注意 如果字典或列表中有中文,序列化时想保留中文
import json
v={'name':'alex','age':18,'cname':'金角大王'}
v1=json.dumps(v)
print(v1)   # {"name": "alex", "age": 18, "cname": "\u91d1\u89d2\u5927\u738b"}

v2=json.dumps(v,ensure_ascii=False)
print(v2)   # {"name": "alex", "age": 18, "cname": "金角大王"}

6.5.2 dump 和 load

import json
v={'name':'alex','age':18,'cname':'金角大王'}
with open ('json.txt',mode='w',encoding='utf-8') as file:
    v1=json.dump(v,file)  # 直接写入文件,json类型的字符串  {"name": "alex", "age": 18, "cname": "\u91d1\u89d2\u5927\u738b"}
    print(v1)
import json
with open ('json.txt',mode='r',encoding='utf-8') as file:
    v1=json.load(file) # 直接读取
    print(v1,type(v1)) # {'name': 'alex', 'age': 18, 'cname': '金角大王'} <class 'dict'>

6.6 copy

6.7 random

6.8 getpass

6.9 shutil

import shutil

# 删除目录
# shutil.rmtree('test')

# 重命名
# shutil.move('test','ttt')

# 压缩文件
# shutil.make_archive('zzh','zip','D:\code\s21day16\lizhong')

# 解压文件
# shutil.unpack_archive('zzh.zip',extract_dir=r'D:\code\xxxxxx\xxxx',format='zip')
import shutil
info = r'D:\YU PHOTOS'
shutil.make_archive('new_file','zip',info) # 文件名 格式 需要压缩的文件路径

shutil.unpack_archive(r'C:\Users\Usher\Desktop\homework\day16\new_file.zip',r'C:\Users\Usher\Desktop\homework\day16\lev1\lev2','zip') # 要解压的文件路径 需要解压到的路径 格式
import os
import shutil
from datetime import datetime
ctime = datetime.now().strftime('%Y-%m-%d-%H-%M-%S') # 时间格式化 变成字符串

# 1.压缩lizhongwei文件夹 zip
# 2.放到到 code 目录(默认不存在)
# 3.将文件解压到D:\x1目录中。

if not os.path.exists('code'): # 如果不存在此目录
    os.makedirs('code') # 创建此目录
shutil.make_archive(os.path.join('code',ctime),'zip','D:\code\s21day16\lizhongwei')
# 文件名(目录+时间格式化) 格式 需要压缩的文件路径
file_path = os.path.join('code',ctime) + '.zip'  # 压缩文件 的 文件路径
shutil.unpack_archive(file_path,r'D:\x1','zip')

6.10 pickle

6.10.1pickle 和 json 的区别

···json,优点:所有语言通用;缺点:只能序列化基本的数据类型 list/dict/int...

···pickle,优点:python中所有的东西都能被他序列化(socket对象);缺点:序列化的内容只有python认识。

6.10.2 dumps 和 loads

import pickle
info = {1,2,3,4}
v1=pickle.dumps(info)
print(v1)   # b'\x80\x04\x95\r\x00\x00\x00\x00\x00\x00\x00\x8f\x94(K\x01K\x02K\x03K\x04\x90.'
v2=pickle.loads(v1)
print(v2)   # {1, 2, 3, 4}
# dumps 和 loads 的功能与json相似,只是可以处理的数据类型更多,几乎所有的数据类型都能被序列化,产生pickle自己的数据

6.10.3 dump 和 load

import pickle
info = {1,2,3,4}
with open ('pickle.txt',mode='wb') as file:
    v=pickle.dump(info,file)   # 写入的是二进制

with open ('pickle.txt',mode='rb') as file:
    v1=pickle.load(file)
    print(v1)   # {1, 2, 3, 4}

6.11 time 和 datetime

6.11.1 时间概念

UTC/GMT:世界时间

本地时间:本地时区的时间。

6.11.2 time

import time
time.time() # 时间戳 从格林威治时间 1970年1月1日 算起的多少秒
time.sleep(1) # 等待时间长度
time.timezone() # 时区

6.11.3 datetime

from datetime import datetime,timezone,timedelta

# ##### 获取datetime格式时间 #####
v1=datetime.now()
print(v1) # 2020-05-12 18:21:10.704385
v2=timezone(timedelta(hours=7)) # 东七区 UTC+07:00
v3=timezone(timedelta(hours=-7)) # 西七区 UTC-07:00
print(datetime.now(v2)) # 东七区时间 2020-05-12 17:21:10.727391+07:00
print(datetime.now(v3)) # 西七区时间 2020-05-12 03:21:10.729390-07:00

# ##### 把datetime格式转换成字符串 #####
v1=datetime.now()
print(v1,type(v1)) # 2020-05-12 18:24:21.681545 <class 'datetime.datetime'>
V2=v1.strftime('%Y-%m-%d %H-%M-%S') # 转换成的格式,中间的连接符可以自定义
print(V2,type(V2)) # 2020-05-12 18-24-21 <class 'str'>

# ##### 字符串转成datetime #####
v1='2020/05/20 20/00/00'
v2=datetime.strptime(v1,'%Y/%m/%d %H/%M/%S') # 列出字符串的格式,方便电脑读取
print(v2,type(v2)) # 2020-05-20 20:00:00 <class 'datetime.datetime'>

# ##### datetime时间的加减 #####
v1='2020/05/20 20/00/00'
v2=datetime.strptime(v1,'%Y/%m/%d %H/%M/%S')
v3=v2-timedelta(days=20) # 减20天
v4=v2+timedelta(weeks=5) # 加5周
v5=v2-timedelta(hours=20) # 减20小时
info1=v3.strftime('%Y-%m-%d %H-%M-%S')
info2=v4.strftime('%Y-%m-%d %H-%M-%S')
info3=v5.strftime('%Y-%m-%d %H-%M-%S')
print(info1) # 2020-04-30 20-00-00
print(info2) # 2020-06-24 20-00-00
print(info3) # 2020-05-20 00-00-00

# ##### 时间戳和datetime关系 #####
import time
v1=time.time()
print(v1) # 打印当前时间戳
v2=datetime.fromtimestamp(v1) # 将此时间戳转换为datetime格式时间
print(v2)

v3=datetime.now() # 获取当前datetime格式时间
v4=v3.timestamp() # 将此时间转换为时间戳
print(v4)

6.11.4 异常处理

try:
    val = input('请输入数字:')
    num = int(val)
except Exception as e:
    print('操作异常')
# import requests
#
# try:
#     ret = requests.get('http://www.google.com')
#     print(ret.text)
# except Exception as e:
#     print('请求异常')
def func(a):
    try:
        return a.strip()
    except Exception as e:
        pass
    return False

v = func('alex')
if not v:
    print('函数执行失败')
else:
    print('结果是',v)
# 练习
# 1. 写函数,函数接受一个列表,请将列表中的元素每个都 +100
def func(arg):
    result = []
    for item in arg:
        if item.isdecimal():
            result.append(int(item) + 100)
	return result 

# 2. 写函数去,接受一个列表。列表中都是url,请访问每个地址并获取结果。
import requests 
def func(url_list):
    result = []
    try:
        for url in url_list:
            response = requests.get(url)
            result.append(response.text)
	except Exception as e:
        pass
	return result 
# 此循环会在遇到google时终止,并不会循环bing

def func2(url_list):
    result = []
    for url in url_list:
        try:
            response = requests.get(url)
            result.append(response.text)
        except Exception as e:
            pass
	return result 
# 此循环会遍历完列表中所有元素

func(['http://www.baidu.com','http://www.google.com','http://www.bing.com'])

第七章 面向对象

第八章 网络编程

第九章 并发编程

第十章 数据库

第十一章 前端开发

第十二章 Django框架

附录 常见错误和单词

1.看代码写结果

def func(*args,**kwargs):
    pass

# a. 请将执行函数,并实现让args的值为 (1,2,3,4)
#  func(1,2,3,4)
# b. 请将执行函数,并实现让args的值为 ([1,2,3,4],[11,22,33])
#  func([1,2,3,4],[11,22,33])
# c. 请将执行函数,并实现让args的值为 ([11,22],33) 且 kwargs的值为{'k1':'v1','k2':'v2'}
#  func([11,22],33,**{'k1':'v1','k2':'v2'})
# d. 如执行 func(*{'武沛齐','金鑫','女神'}),请问 args和kwargs的值分别是?   ************
#  args ('武沛齐','金鑫','女神') kwargs {}
# e. 如执行 func({'武沛齐','金鑫','女神'},[11,22,33]),请问 args和kwargs的值分别是?******
#  args ({'武沛齐','金鑫','女神'},[11,22,33]) kwargs {}
# f. 如执行 func('武沛齐','金鑫','女神',[11,22,33],**{'k1':'栈'}),请问 args和kwargs的值分别是?**************
#   args ('武沛齐','金鑫','女神',[11,22,33])  kwargs {'k1':'栈'}

2.看代码写结果

def func(name,age=19,email='123@qq.com'):
    pass

# a. 执行 func('alex') ,判断是否可执行,如可以请问 name、age、email 的值分别是?
# 可执行 位置参数在前,关键字参数有默认值,name=alex,age=19,email='123@qq.com'
# b. 执行 func('alex',20) ,判断是否可执行,如可以请问 name、age、email 的值分别是?********
# 可执行  name=alex age=20 email=123@qq.com
# c. 执行 func('alex',20,30) ,判断是否可执行,如可以请问 name、age、email 的值分别是?******
# 可执行  name=alex age=20 email=30
# d. 执行 func('alex',email='x@qq.com') ,判断是否可执行,如可以请问 name、age、email 的值分别是?
# 可执行 name=alex age=19 email=x@qq.com
# e. 执行 func('alex',email='x@qq.com',age=99) ,判断是否可执行,如可以请问 name、age、email 的值分别是?
# 可执行 name=alex,email='x@qq.com',age=99
# f. 执行 func(name='alex',99) ,判断是否可执行,如可以请问 name、age、email 的值分别是?
# 不可执行
# g. 执行 func(name='alex',99,'111@qq.com') ,判断是否可执行,如可以请问 name、age、email 的值分别是?
# 不可执行

3.写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回。

def func(data_list):
    new_list=data_list[1::2]   
    return new_list

info=(1,2,3,4,5,6)
v=func(info)
print(v)

4.写函数,在函数内部生成如下规则的列表 [1,1,2,3,5,8,13,21,34,55…](斐波那契数列),并返回。 注意:函数可接收一个参数用于指定列表中元素最大不可以超过的范围。

import time
def func(max_range):
    result=[1,1]
    while True:
        val=result[-1]+result[-2]
        if val>max_range:
            break
        result.append(val)
        time.sleep(1)
        print(result)

func(100)

5.看代码写结果

v1 = [1,2,3,4,5]
v2 = [v1,v1,v1]  #  *******

v1.append(6)
print(v1) # [1,2,3,4,5,6]
print(v2) # [[1,2,3,4,5,6],[1,2,3,4,5,6],[1,2,3,4,5,6]]

6.看代码写结果,并解释每一步的流程。

v1 = [1,2,3,4,5,6,7,8,9]
v2 = {}

for item in v1:
    if item < 6:
        continue
    if 'k1' in v2:
        v2['k1'].append(item)
	else:
        v2['k1'] = [item ]
print(v2)    #  {'k1':[6,7,8,9]}

7.看代码写结果

import copy

v1 = [1,2,3,{"name":'武沛齐',"numbers":[7,77,88]},4,5]

v2 = copy.copy(v1)

print(v1 is v2) # False

print(v1[0] is v2[0]) # True
print(v1[3] is v2[3]) # True

print(v1[3]['name'] is v2[3]['name']) # True
print(v1[3]['numbers'] is v2[3]['numbers']) # True
print(v1[3]['numbers'][1] is v2[3]['numbers'][1]) # True

8.看代码写结果

import copy

v1 = [1,2,3,{"name":'武沛齐',"numbers":[7,77,88]},4,5]

v2 = copy.deepcopy(v1)

print(v1 is v2) # False

print(v1[0] is v2[0]) # True
print(v1[3] is v2[3]) # False

print(v1[3]['name'] is v2[3]['name']) # True
print(v1[3]['numbers'] is v2[3]['numbers']) # False
print(v1[3]['numbers'][1] is v2[3]['numbers'][1]) # True

9.请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:将被装饰的函数执行5次,讲每次执行函数的结果按照顺序放到列表中,最终返回列表。

import random 
def index(data):
    def inner(*args,**kwargs):
        info=[]
        for i in range(5):
            v=data(*args,**kwargs)
            info.append(v)
        return v
    return inner

@index
def func():
    return random.randint(1,4)

func() # 执行5次,并将每次执行的结果追加到列表最终返回给result
print(info)

10.请为以下函数编写一个装饰器,添加上装饰器后可以实现:执行 read_userinfo 函时,先检查文件路径是否存在,如果存在则执行后,如果不存在则 输入文件路径不存在,并且不再执行read_userinfo函数体中的内容,再讲 content 变量赋值给None。

import os
def index(info):
    def inner(*args,**kwargs):
        result = os.path.exists(args[0])
        if not result:
            print('路径不存在')
            return None
        data=info(*args,**kwargs)
        return data
    return inner

@index
def read_userinfo(path):
    file_obj = open(path,mode='r',encoding='utf-8')
    data = file_obj.read()
    file_obj.close()
    return data

content = read_userinfo('/usr/bin/xxx/xxx')

"""
温馨提示:如何查看一个路径是否存在?
import os
result = os.path.exists('路径地址')

# result为True,则表示路径存在。
# result为False,则表示路径不存在。
"""

 

posted @ 2020-05-17 09:20  投降输一半!  阅读(166)  评论(0编辑  收藏  举报