Python基础学习总结

Python120天

预科三天(安装基本软件)

1.Python和PyCharm的安装

2.Git和码云

码云常用命令

git add .
git commit -m "备注信息"
git push -u origin master  上传
git pull origin master 把码云上的代码下载到本地
git pull origin master --allow-unrelated-histories解决本地两个文件上传的冲突
git remote add origin IP地址

​ 1.Markdown常用语法

​ 2.博客园使用

​ 3.思维导图制作

​ 4.排bug技巧

3.Typora安装

markdown语法

1.标题

  • 用 #+空格 实现

    这是一个一级标题

    ...

    这是一个六级标题

2.代码块

三个```实现一个代码块

这是单行代码块效果 用一对``实现

3.列表

  • 有序列表

    1.跟内容

    2.跟内容

    ...

  • 无序列表

    • -跟内容
    • +跟内容
    • *跟内容

4.链接

[目标地址名称](目的地IP地址)

百度

5.键盘快捷键之缩进

  • 往前缩进shift+tab
  • 往后缩进tab

6.图片

  • md文件传输时图片丢失的解决方法
    • 保存时,点击左上角的文件,导出为PDF格式
    • 借助网络上的平台,把图片上传上去,然后用网络地址代替

7.分割线

---实现分割线

+++实现分割线

***实现分割线

8.字体样式

  • 加粗

    **加粗**

  • 倾斜

    **

4.XMind思维导图

应用场景

1.有层级关系

2.从大范围到具体

思维导图制作工具

XMind

  • 常用快捷键
    • 建立自分支Tab键
    • 建立兄弟分支Enter键

5.博客

博客发表条件

1.新技术,以自己的观点发表

2.借鉴国外的一些新技术或者新研究

3.自己的笔记,要求自己的笔记成体系

博客园中有学不完的技术

6.排BUG技巧

1.根据错误类型推算,错误哪里出的问题,找具体代码重新审核

2.百度搜索或者谷歌搜索

3.stackoverflow

4.建议自己组一个BUG集合,发布到博客上,以便查验和分享

第一章

一、Python简介

  1. python2: 源码不统一,有重复 (更新维护到2020年)

    python3: 源码统一,无重复

    python2:python2中print不用,print "内容"

    python3:Python3中print必须用括号括起来,print("内容")

    python2:数字Python2中input得到的为int

    python3:python3中input得到的为str

    Python是一门动态解释型的强类型定义语言

二、变量

  1. 变量命名规则
    • 由数字、字母、下划线组成
    • 不能以数字开头
    • 要具有描述性
    • 要区分大小写
    • 禁止使用python的关键字
    • 不能使用汉字或拼音(low)
    • 变量的推荐写法
      • 驼峰体
      • 下划线(官方推荐)

三、常量

变量全部用大写命名,就是常量

四、注释

  1. 单行注释

    • 也叫当行注释 用#号
    • 用于当行的注释
  2. 多行注释

    """

    """

    三个引号,文档注释,描述文件或者函数使用的注释

五、基础数据类型

  1. 字符串 str

    • "字符串asdasdasdada"
      • str + str(字符串的拼接)
      • str * int(实现字符串成int倍的拼接)
  2. 整形(数字) int

    • 用于比较和计算

      python2:除法的时候返回的是整数(向下取整)

      python3:除法的时候返回的的小数(浮点数)

  3. 布尔值 bool

    • 用于判断
      • True ——真
      • False——假

六、用户交互

  1. input —— 输入:python3中input获取到的内容都是字符串

  2. print —— 输出

    number = input("请输入您内容:")
    print(number)

七、查看数据类型

  1. type

    • 查看数据类型
      • int(str) —— 将字符串转换成整形
      • str(int) —— 将整形转换成字符串

    type(需要检测的对象)

八、流程控制语句

  1. 单 if

    • if 条件:

      缩进 结果

      money = 10
      print("从学校出发")
      if money >= 10:
          print("买个炸鸡")
          print("买个啤酒")
      print("走啊走")
      print("到家了")
  2. 二选一 ,if else

    • if 条件:

      缩进 结果

      else:

      缩进 结果y

      if 3>2:
          print("这是如果执行了")
      else:
          print("这是否则执行了")
  3. 多选一或不选 if elif elif elif

    • if 条件:

      缩进 结果

      elif 条件:

      缩进 结果

      elif 条件:

      缩进 结果

      if 1>2:
          print("这是A")
      elif 1>6:
          print("这是B")
      elif 1>5:
          print("这是C")
      elif 1>4:
          print("这是D") # 没有符合要求的就不输出结果
  4. 多选一 if elif elif else

    • if 条件:

      缩进 结果

      elif 条件:

      缩进 结果

      elif 条件:

      缩进 结果

      else :

      缩进 结果

      if 1>2:
          print("A")
      elif 2>3:
          print("B")
      elif 5>6:
          print("c")
      else:
          print("D")
  5. if 嵌套

    • if 条件:

      缩进 结果

      ​ if 条件:

      ​ 缩进 结果

    score
    if score > 500:
        if score > 700 :
            print("北大清华")
        else:
            print("随便找一个大学")
    else:
        print("分不够,不能上大学")

第二章

一、while循环

基础循环

while 条件:
    循环体
例如:
while True:
    print("Hello World")
# ctrl + C 终止程序

运行上面的代码会陷入死循环,使用while时一定不能陷入死循环,需要加条件,如下代码

flag = True
while flag:
    print("循环体代码")
    flag = False   #把flag改为假

使用while计数输出,输出0-99

count = 0
while count < 100:
    print("count")
    count += 1    #每次循环进行自增

break关键字

用于中断循环,通常再满足某种条件时使用,如下,我希望在等于10时终止程序

num = 1
while num < 6:
    print(num)
    if num == 3:
        break
    print("结束")     #当num=3时,break,并且下面的代码不执行

continue关键字

用于结束本次循环,仅仅跳出本次,例如,输出1-10,但是不输出3

num = 1
while num < 11:
    if num == 3:
        continue   #当代码执行到这里,结束本次循环,后面的代码不执行,表现为不输出3
    print(num)

while else使用

# 如下代码执行结果为456,是因为满足了while的条件,执行了内部的代码,遇到break终止了程序,所以else内代码不执行
i = 11
while i < 15:
    print("456")
    i += 1
    break
else:
    print("123")
# 如下代码执行结果为123,因为while条件不满足,内部代码不执行,直接执行else内部的代码
i = 11
while i < 10:
    print("456")
    i += 1
    break
else:
    print("123")
# 如下代码的结果为四遍456,一遍123,当执行完while内部代码之后,还会执行else 内部的代码
i = 11
while i < 15:
    print("456")
    i += 1
else:
    print("123")

二、格式化输出

现在需要录入身边好友的信息,格式如下

------------ info of user ----------
             Name  : 
             Age   : 
             job   : 
             Hobbie: 
    ------------- end ----------------
用print,过于死板,代码太长
name = input('请输入姓名:')
age = input('请输入年龄:')
job = input('请输入职业:')
hobby = input('请输入爱好:')
a = '------------ info of user ----------'
b = 'Name:'
c = 'Age:'
d = 'Job:'
e = 'Hobby:'
f = '------------- end ----------------'
print(a)
...
print(f)

# 运行结果
------------ info of user ----------
Name:123
Age:456
Job:456
Hobby:789
------------- end ----------------
使用字符串
name = input('请输入姓名:')
age = input('请输入年龄:')
job = input('请输入职业:')
hobby = input('请输入爱好:')
msg = '''
------------ info of Alex Li ----------
Name  : %s
Age   : %s 
job   : %s 
Hobbie: %s 
------------- end ----------------
'''
print(msg%(name,age,job,hobby))

%是一个占位,s是用来声明类型的,s是字符串类型

还有数字类型%d或%i,用来接收数字,

age = int(input("请输入你的年龄"))    # 需要用int把输入的字符串变成整型
print("你的年龄是%d" % age)

%% 转义

number = input('>>>')
s= '目前学习进度:%s%%'%num     #当出现%,解释器认为是占位,但是后面没有声明类型,出现错误,必须用%转义,这样解释器就认为这是一个%
print(s)

常用运算符

  • 算数运算
  • 比较运算
  • 逻辑运算
  • 赋值运算

算数运算符

  • /
  • ** 幂
  • % 取模
  • // 取整除,向下取整

比较运算

== != >= <= > <

赋值运算

= 简单的赋值运算符 a= b+c
+= 加法赋值运算符 a = a+c 等效于 a+=c
-= 减法赋值运算符 a = a-c 等效于 a-=c
/= 除法赋值运算符 a = a/c 等效于 a/=c
*= 乘法赋值运算符 a = ac 等效于 a=c
**= 幂赋值运算符 a = ac 等效于 a=c
//= 取整除赋值运算符 a = a//c 等效于 a//=c
%= 取模赋值运算符 a = a%c 等效于 a%=c

逻辑运算

运算符 描述
and 两边同为True,返回true
or 两边只要有一个true,返回true
not 取反
# True and False
# 数字非零的都是真

# and 的运算,都为真才是真,有一个是假就是假
# and 的运算,都为真的的时候选择and后边的内容
# and 的运算,都为假的的时候选择and前边的内容

# or 的运算,只要有一个真就是真
# or 的运算,都为真的的时候选择or前边的内容
# or 的运算,都为假的的时候选择or后边的内容

成员运算

in,not in

判断元素是否在原字符串中,例如

print('x' in 'next')

print('a' in 'love')

三、初始编码

ASCll

只支持英文,不支持中文,占一个字节

GBK(国标码)

兼容ASCLL码

占两个字节

Unicode(万国码)

为了兼容世界的所有语言,但是太过浪费资源

UTF-8(unicode的扩展集)

UTF-8为了节省资源,采用变长编码

英文1个字节

欧洲2个字节

亚洲3个字节

单位转化

8bit = 1byte
1024byte = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
1024TB = 1PB
1024TB = 1EB
1024EB = 1ZB
1024ZB = 1YB
1024YB = 1NB
1024NB = 1DB
常⽤到TB就够了

第三章

今日内容

1.整型

2.布尔值

3.字符串

索引 切片 步长 字符串的方法

4.for循环

1.整型

  • python3:全部是整形
  • python2:整形,长整型long
  • 用于计算和比较

2进制 - 10进制

0 * 2 ** 0 + 1 * 2 ** 1 +1 * 2** 2+ 1 * 2 ** 3 +...

10进制 -2进制(断除法)

2.布尔值

  • 布尔值、整形、字符串转换
    • 整型中只要是非零的就是True
    • 布尔值 0 -- False 1 -- True
    • 字符串中只要没有内容就是False

3.字符串

python中只要是引号引起来的就是字符串

字符串:用于数据存储,存储少量数据

字符串中每一个字符或者字母都成为元素

索引(下标)

"name"
 0123
 -4-3-2-1
 #从左往右排,一一对应,通过下标读取数据,从0开始
 a = 'yi_yi_dui_ying'
 print(a[5])
 print(a[6])
 ...
 #索引的时候不能超出最大索引值

切片步长

# [索引值]  [起始位置(包含):终止位置(不包含)]
a = 'yi_yi_dui_ying'
print(a[1:2])
print(a[-1:])
# print(a[:])    [(默认从最开始):(默认到最后)]
# 步长决定查找的方向 1是从左往右,-1是从右往左
练习
a = 'weixin,teng,腾讯,百度,阿里'
# 1.腾讯
print(a[12:14])
# 2.ii
print(a[2:6:2])
# 3.阿度
print(a[-2:-5:-2])
# 4.整体反转
print(a[::-1])

字符串方法

字符串是不可变数据类型,字符串是有序的

# name = "qwer"
# a = name.upper()  # 全部大写
# print(a)
# print(name)

# name = "WQEW"
# a = name.lower()   # 全部小写
# print(name)
# print(a)

# name = "qwer"
# print(name.startswith('e',2,3))  # 以什么开头 -- 返回的是布尔值
# print(name.endswith('l',0,2))    # 以什么结尾 -- 返回的是布尔值

# name = "alexwusirtaibIa"
# print(name.count("i"))      # 统计,计数

user = input("user_name:").strip()  # 去两边的空格制表符\n,换行符\t

# name = "xu_yu_wei"
# a = name.split("_")        # 分割(默认空格,换行符\n,制表符\t)
# print(a)                   # ['xu','yu','wei']

# name = "alex,wusir,ta,i,b,a,i"
# a = name.replace(",",".")               # 全部替换
# print(a)

# a = name.replace(",",".",4)              # 可以指定替换的次数
# print(a)

# 字符串格式化(字符串的方法)
# name = "{}今年:{}".format("佳成",18)    # 按照位置顺序进行填充
# print(name)


msg = "QWer"
# print(msg.isdigit())      # 判断字符串中的内容是不是全都是数字(阿拉伯数字)
# print(msg.isdecimal())    # 判断是不是十进制数
# print(msg.isalnum())      # 判断是不是数字,字母,中文
# print(msg.isalpha())      # 判断是不是字母,中文

# 总结:
#     upper        全部大写
#     lower        全部小写
#     startswith   以什么开头
#     endswith     以什么结尾
#     count        计算出现的次数
#     strip        去空格
#     split        分隔符
#     replace      替换符
#     format       填充占位符
#     isdecimal()  判断是不是十进制数
#     isalnum()    判断是不是数字字母和中文
#     isalpha()    判断是不是字母、中文
#     isdigit()    判断字符串中的内容是不是全都是数字(阿拉伯数字)

4.for循环

# for 关键字
# i   变量名(可以任意修改)
# in  关键字
# msg 可迭代对象

# 可迭代对象: Python数据类型中 除了int,bool其余都可以迭代

msg = "文能提笔安天下,无能马上定乾坤"
for a in msg:
    print(a)
print(a)

第四章

今日内容

  • 列表
  • 元组
  • range

列表

列表相比于字符串,不仅可以储存不同的数据类型,而且可以储存大量数据,是一种可变的数据类型

64位python的限制是 1152921504606846975 个元素。而且列表是有序的,有索引值,可切片,方便取值

1.列表的增加

lst = ['q','w','e','r',5,9]
lst.append(10)          #追加,在最末尾的地方进行添加

lst.insert(2, 's')      #插入,在指定的索引值进行添加

lst.extend([1,2,3,4])   #迭代添加,把迭代的元素一个一个添加进列表

for i in [1,2,3,4]:
    lst.append(i)       # 把数据一个一个添加进列表

2.列表的修改

lst = [1,3,4,5,6,34]
lst[1] = 99             #通过索引值删除

lst[1:3] = "20"         #通过切片进行修改,默认步长是1,必须是可迭代对象,修改的内容可多可少

lst[1:5:2] = 1000,100   #步长不为1的时候,必须一一对应

3.列表的删除

lst = ['q','w','e','r']
print(repr(lst.pop(2)))    #默认删除最后一个元素并返回,repr()查看当前数据的原生态

lst.clear()                 #清空列表

del lst[2]
del lst[0:2]                # 通过切片删除
del lst[1:4:2]              # 通过步长删除

4.列表的查

lst = [1,1,8,7,9]
for循环
for i in lst:
    print(i)
    
索引
lst[索引下标]

5.列表的嵌套

lst = ['one','two',['basketball',['dance','apple'],['score','qwer']],
['a','three','wqer']]
通过索引下标随便指定并取出
basketball
print(lst[2][1])

元组

tuple不可变数据类型,只支持查询

元组的方法

  • 获取索引
  • 统计
tu = (1,2,3,4,5,6,7,8,9)
print(tu.count(1))
print(tu.index(2))          # 通过元素查询索引

range

range的诞生是为了解决不能循环数字

for i in range(2,10,2):
    print(i)

for i in range(100):
    print(i)
    
range(1,10)   #  [起始位置:终止位置]  顾头不顾尾
range(1,10,2) #  [起始位置:终止位置:步长] 默认为 1
range(10)    #  10代表的是终止位置,起始位置默认为 0
range是一个可迭代对象

第五章

今日内容

  • 字典

字典

语法:{'key1':1,'key2':2}

注意:dict保存的数据不是按照我们添加进去的顺序保存的. 是按照hash表的顺序保存的. ⽽hash表 不是连续的. 所以不能进⾏切片⼯作. 它只能通过key来获取dict中的数据

列表可以存储大量的数据类型,但是只能按照顺序存储,数据与数据之间关联性不强。为了解决这一问题,就需要用字典。字典(dict)是python中唯⼀的⼀个映射类型.他是以{ }括起来的键值对组成

在dict中key是 唯⼀的.在保存的时候, 根据key来计算出⼀个内存地址. 然后将key-value保存在这个地址中.

这种算法被称为hash算法,key必须是可hash的

已知的可哈希(不可变)的数据类型: int, str, tuple, bool 不可哈希(可变)的数据类型: list, dict, set

注意: key必须是不可变(可哈希)的. value没有要求.可以保存任意类型的数据

注意:dict保存的数据不是按照我们添加进去的顺序保存的. 是按照hash表的顺序保存的. ⽽hash表 不是连续的. 所以不能进⾏切片⼯作. 它只能通过key来获取dict中的数据

dict = {1:1,2:2,3:'3',4:'5'}
print(dict[1])          # 1
print(dict[4])          # '5'

注意:dict保存的数据不是按照我们添加进去的顺序保存的. 是按照hash表的顺序保存的. ⽽hash表 不是连续的. 所以不能进⾏切片⼯作. 它只能通过key来获取dict中的数据

1.字典的增

dic = {}

dic['name'] = '徐'
dic['age'] = 19
print(dic)                  # {'name': '徐', 'age': 19}

# 如果dict中没有出现这个key,就会将key-value组合添加到这个字典中
# 如果dict中没有出现过这个key-value. 可以通过setdefault设置默认值

dic.setdefault('雨隹',1)
print(dic)                  # {'雨隹': 1}  
# 我们使用setdefault这个方法 里边放的这个内容是我们字典的健,后面写默认值,可不写,默认为None

dic.setdefault('雨隹',123)    
# 这样就是不会进行添加操作了,因为dic这个字典中已经存在
# 总结: 当setdefault中第一个参数存在这个字典中就不进行添加操作,否则就添加

2.字典的删

dic = {'剑圣':'易','哈啥给':'剑豪','大宝剑':'盖伦'}
s = dic.pop('剑圣')                            # pop删除有返回值,返回的是被删的值
print(dic)    # 打印删除后的字典

dic.popitem()  # 随机删除  python3.6是删除最后一个
print(dic)

dic.clear()  # 清空

3.字典的改

dic = {'剑圣':'易','哈啥给':'剑豪','大宝剑':'盖伦'}
dic['大宝剑'] = '德玛西亚'
print(dic)

dic.update({'key':'v','哈啥给':'剑姬'})
# 当update中的字典里没有dic中键值对就添加到dic字典中,如果有就修改里边的对应的值,必须是字典

4.字典的查

dic = {'剑圣':'易','哈啥给':'剑豪','大宝剑':'盖伦'}
s = dic['大宝剑']              #通过健来查看,如果这个健不在这个字典中.就会报错

s1 = dic.get('剑圣')          #通过健来查看,如果这个健不在这个字典中.就会返回None

s2 = dic.get('剑姬','可定义返回的结果')  # 我们可以在get查找的时候自己定义返回的结果

5.字典的其他操作

    keys()              获取所有的键
    values()            获取所有的值
    items()             获取所有的键值
    for循环   --         循环的是字典的键
for k,v in dic.items():
    print('这是键',k)
    print('这是值',v)
#   循环字典获取键和值

练习

dic = {'k1': "v1", "k2": "v2", "k3": [11,22,33]}
请在字典中添加一个键值对,"k4": "v4",输出添加后的字典
请在修改字典中 "k1" 对应的值为 "alex",输出修改后的字典
请在k3对应的值中追加一个元素 44,输出修改后的字典
请在k3对应的值的第 1 个位置插入个元素 18,输出修改后的字典

6.结构

a,b = 1,2
print(a,b)                      #   1 2

a,b = ('你好','世界')
print(a,b)                      # 你好,世界

a,b = {'汪峰':'北京北京','王菲':'天后'}
print(a,b)
结果:
汪峰 王菲

解构可以将内容分别赋值到变量当中,我们使用解构就能够快速的将值使用

7.字典的嵌套

dic = {
    101:{1:{"日魔":"对象"},
         2:{"隔壁老王":"王炸"},
         3:{"乔碧萝":("日魔","炮手","宝元")},
         },
    102:{1:{"汪峰":{"国际章":["小苹果","大鸭梨"]}},
         2:{"邓紫棋":["泡沫","信仰","天堂","光年之外"]},
         3:{"腾格尔":["隐形的翅膀","卡路里","日不落"]}
         },
    103:{1:{"蔡徐坤":{"唱":["鸡你太美"],
                   "跳":["钢管舞"],
                   "rap":["大碗面"],
                   "篮球":("NBA形象大使")}},

         2:{"JJ":{"行走的CD":["江南","曹操","背对背拥抱","小酒窝","不潮不花钱"]}},
         3:{"Jay":{"周董":["菊花台","双节棍","霍元甲"]}}},

    201:{
        1:{"韦小宝":{"双儿":"刺客","建宁":{"公主":{"吴三桂":"熊"}},"龙儿":{"教主老婆":"教主"}}}
    }
}
print(dic[201][1]["韦小宝"]["建宁"]["公主"]["吴三桂"])
# print(dic[103][1]["蔡徐坤"]["跳"][0][1])
# print(dic[102][2]["邓紫棋"][1])

练习

dic1 = {
 'name':['alex',2,3,5],
 'job':'teacher',
 'oldboy':{'alex':['python1','python2',100]}
 }
1,将name对应的列表追加⼀个元素’wusir’。
2,将name对应的列表中的alex⾸字⺟⼤写。
3,oldboy对应的字典加⼀个键值对’⽼男孩’,’linux’。
4,将oldboy对应的字典中的alex对应的列表中的python2删除

第六章

今日内容

  • 小数据池
  • 深浅拷贝
  • 集合

小数据池

  • == is id

    == 判断两个值是否相等

    is --- 是 判断两个值的内存地址是否相等

  • 代码块:一个py文件,一个函数,一个模块,终端中每一行都是代码块

代码块中有自己的内存空间:int ,str ,bool

int:-2~正无穷

a = -6
b = -6
print(a is b)

a = 1000
b = 1000
print(id(a), id(b))
print(a is b)

str:

  • 字符串:
    • 定义字符串的时候是任意的
    • 字符串(字符和数字)进行乘法时总长度不超过20
    • 特殊符号(中文,符号)进行乘法的 时候乘以0 或 1
      • 字符串:
        • 定义字符串的时候内容,长度任意内存地址相同。
        • 字符串进行乘法的时候总长度 <=20 内存地址相同。
        • 中文,特舒符号 乘法的时候只能乘以1或 0

bool:

​ True,False

小地址池 -- int,str , bool

int:-5~ 256

str:

  • 纯字母和数字的时候长度任意,内存地址相同。
  • Python36纯字母和数字乘法总长度 <= 20 内存地址相同。
  • Python37纯字母和数字乘法总长度 <= 4096 内存地址相同。
  • 中文和特殊符号乘法的时候只能乘以 0 内存地址相同

驻留机制:节省内存空间,提升效率(减少了开辟空间和销毁空间的耗时)

深浅拷贝

赋值, =
a = [1,2,3,4]
b = a
print(id(a),id(b))
print(a is b)
# a和b的内存地址一样,任何一个改,其他的改都改
浅拷贝
# 在列表的元素中,元素是列表的情况下,拷贝的是内存地址
# 当内部的元素发生改变时,拷贝的列表和原列表都发生改变
a = [1,2,3,[4,5]]
b = a[:]  
# 浅拷贝a[-1].append(6)
print(b)
深拷贝
import copy  # 导入 copy模块
a = [1,2,3,[4,5],6]
b = copy.deepcopy(a)
print(id(a[-2]))
print(id(b[-2]))

print(a)
print(b)
print(a == b)
print(id(a),id(b))
print(a is b)
# 不可变数据类型内存地址共用,可变数据类型新开辟一个空间 不管嵌套多深

集合

集合中的元素要求是不可变的并且还是唯一的,我们就利用它是唯一来做去重

集合 -- set

s = {1,2,3,4}

  • 集合就是一个没有值得字典,无序,可变; 值是唯一,不可变的

  • 天然集合去重

    s = {1,1,2,3,4,1,1,1,1}

s = {}       # 空字典
s1 = set()   # 空集合
print(type(s1))
print(type(s))
集合的增:
s = set()
s.add('one')
s.update('two')         #不建议使用
set('12345')            #后面跟可迭代对象,只能迭代添加到空集合
集合的删:
s = {100, 200 ,500 , 10 , 0.1, 0.5}
s.remove(500)           # 通过元素删除
s.clear()               # 清空列表
s.pop()                 # 随机删除
集合的改

先删除,后添加,没有改的方法

集合的查

for循环

其他操作

s = {1, 24, 25, 48, 98, 56}

s_ = {1, 24, 25}

  • 差集 -
print(s - s1)
print(s1 - s)
  • 交集 &
print(s & s1)
  • 并集 |
print(s | s_)
  • 反交集 ^
print(s ^ s_)
  • 子集 返回一个布尔值
print(s > s_)
  • 父级
print(s_ > s )
  • 冻结集合
print(frozenset({1, 24, 5,4}))

第七章

今日内容

  • 基础数据类型补充
  • 以后会遇到的坑
  • 二次编码

基础类型补充

str
a = "One two"
print(a.capitalize())   # 首字母大写
print(a.title())        # 每个单词首字母大写
print(a.swapcase())     # 大小写转换
print(a.center(20,"=")) # 居中 - 填充
print(a.find("c"))        # 查找 通过元素查找索引,查找不到时返回-1
print(a.index("c"))       # 查找 通过元素查找索引,查找不到时就报错
print("_".join(["1","2","4"]))  # 拼接,将列表转换成字符串
str + str
str * 5
#字符串进行加操作,乘操作都是开辟新的空间
list
# 列表的一种定义方法
print(list('123445'))
# 列表的方法:
lst = [1,23,4,5,7,8,9]
print(lst.index(4))        # 通过元素查找索引
lst.sort()                 # 排序 默认是升序
lst.sort(reverse=True)     # 降序

lst.reverse()               #将源数据进行反转
print(lst)

lst = [1,5,7,9,4,23,546,78]
lst1 = lst[::-1]            #不修改源数据进行反转
dict
dic = {"key":1,"key1":2,"key2":4,"key3":1}
print(dic.popitem())   # 随机删除  python3.6版删除最后一个键值对 
#popitem返回的是被删除的键值对
print(dic)

dic = {}
dic = dic.fromkeys("abc",[])
print(dic)
dic["b"] = 11
dic["a"].append(10)
print(dic)

运行结果:
{'a': [], 'b': [], 'c': []}
{'a': [10], 'b': 11, 'c': [10]}

fromkeys 第一个参数必须是可迭代对象,会将可迭代对象进行迭代,成为字典的键.第二个参数是值(这个值是共用的)
fromkeys 共用的值是可变数据类型就会有坑,不可变数据类型就没事
基础数据类型总结:
可变,不可变,有序,无序
1.可变:
     list
     dict
     set
2.不可变:
    int
    str
    bool
    tuple
3.有序:
    list
     tuple
     str
4.无序:
     dict
     set
取值方式:

    1.索引
        list
        tuple
        str
    
    2.键
        dict
    
    3.直接
        int
        bool
        set

数据类型转换
str -- int
int -- str
str -- bool
bool -- str
int  -- bool
bool -- int
重要: *****
list -- str
lst = ["1","2","3"]
print("".join(lst))

str -- list
s = "alex wusir 太白"
print(s.split())

目前字典转换,自己实现方法
重点
重点:
find
join
列表乘法
元组(1,)
list -- str
str -- list

以后会遇到的坑

  • 死循环
lst = [1,2,3]
for i in lst:
    lst.append(4)
  • 用for循环删除所有元素
# 错误示范
lst = [11,22,33,44]
for i in lst:
    lst.remove(i)
print(lst)

# 正确代码
lst = [11,22,33,44]
for i in range(len(lst)):
    del lst[-1]
print(lst)

for i in range(len(lst)):
    lst.pop()
print(lst)

# 创建一个浅拷贝的列表,循环它的次数,删除源数据的数据
lst = [11,22,33,44]
lst1 = lst[:]
for i in lst1:
    lst.remove(i)
print(lst)

使用for循环清空列表元素内容 1.从后向前删除, 2.创建一个新的容器,循环新的容器删除旧的容器内容

面试题:
lst = [1,[2]]
lst[1] = lst
print(lst)
    
答案: [1, [...]]

字典和集合

dic = {"key":1,"key1":2}

for i in dic:
    if i == "key1":
        dic[i] = dic[i] + 8  # dic[i] = 10
    else:
        print("没有这个键!")
print(dic)

字典和集合在遍历(循环)时不能修改原来的大小(字典的长度),可以进行修改值

# 以下会报错
s = {1,2,3,4,5,6}
for i in s:
    s.pop()
print(s)
Set changed size during iteration

二次编码必会

# python3: 默认编码unicode
# pyhton2:默认编码ascii,不支持中文

print(s.encode("UTF-8")) # 中⽂编码成UTF-8 print(s.encode("GBK")) # 中⽂编码成GBK 结果: b'\xe4\xb8\xad' b'\xd6\xd0'

解码 print(s.decode("utf-8")) print(s.decode('gbk'))

第八章

今日内容

文件操作

  • 读操作
  • 写操作
  • +操作
  • 其他操作

读操作

r模式
f = open('test.txt', mode='r', encoding='utf-8')
print(f.read())
f.close()

with open('test.txt', 'r', encoding='utf-8')as f:
    print(f.read())
    
# 两种方式获得文件句柄,推荐with,运行完之后自动关闭文件
rb模式
with open('test.txt', 'rb', encoding='utf-8')as f:
    print(f.read())
# 读出来的是字节

建议使用相对路径

读操作

f.read()                # 不建议用
f.read(读取的字符数)
f.readline()    # 每次读取一行,每行最后有一个\n
f.readlines()  # 将每一行形成一个元素,并添加到一个列表中,当文件过大时,内存会崩
推荐使用,先拿到文件句柄
with open('1','r',encoding='utf-8')as f:
    for i in f:
        print(i)

写操作

使用w模式的时候,在打开文件的时候就就会把文件中的所有内容都清空,然后在操作
如果文件不存在使用w模式会创建文件,文件存在w模式是覆盖写,在打开文件时会把文件中所有的内容清空.
f.write()

wb模式下,不可以指定打开文件的编辑,但是写文件的时候必须将字符串转换成utf-8的bytes数据

追加

只要是a或者ab,a+都是在文件的末尾写入,不论光标在任何位置.
在追加模式下,我们写入的内容后追加在文件的末尾
a模式如果文件不存在就会创建一个新文件
ab模式和上面一样,没有太大区别
# 面试题:
# 当文件较大时,使用for循环进行读取
# f = open('t1',mode="r",encoding="utf-8")
# for i in f:
#     print(i.strip())

r+模式

r+模式一定要记住是先读后写

f1 = open('test.txt',mode='r+',encoding='utf-8')
msg = f1.read()
f1.write('千山鸟飞绝,万径人踪灭')
f1.flush()
f1.close()
print(msg)
结果:
正常的读取之后,写在结尾
深坑请注意: 在r+模式下. 如果读取了内容. 不论读取内容多少. 光标显示的是多少. 再写入 或者操作文件的时候都是在结尾进行的操作.

w+模式

先将所有的内容清空,然后写入.最后读取.但是读取的内容是空的,不常用

a+模式

a+模式下,不论是先读还是后读,都是读不到数据的

其他操作

seek()
seek(n)光标移动到n位置,注意: 移动单位是byte,所有如果是utf-8的中文部分要是3的倍数
通常我们使用seek都是移动到开头或者结尾
移动到开头:seek(0,0) 可以看做成seek(0)
seek(6)这种如果是单数并且不是0的就是按照字节来移动光标
移动到结尾:seek(0,2) seek的第二个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾
tell()
使用tell()可以帮我们获取当前光标在什么位置

文件修改

文件修改: 只能将文件中的内容读取到内存中, 将信息修改完毕, 然后将源文件删除, 将新文件的名字改成老文件的名字
错误示范,使用read,当文件内容过大,会导致内存溢出
import os
with open("../path1/小娃娃", mode="r", encoding="utf-8") as f1,\
open("../path1/小娃娃_new", mode="w", encoding="UTF-8") as f2:
    content = f1.read()
    new_content = content.replace("冰糖葫芦", "⼤白梨")
    f2.write(new_content)
os.remove("../path1/小娃娃") # 删除源文件
os.rename("../path1/小娃娃_new", "小娃娃") # 重命名新文件
弊端: ⼀次将所有内容进行读取. 内存溢出. 解决方案: 一行一行的读取和操作

正确代码:
import os
with open("小娃娃", mode="r", encoding="utf-8") as f1,\
open("小娃娃_new", mode="w", encoding="UTF-8") as f2:
    for line in f1:
        new_line = line.replace("大白梨", "冰糖葫芦")
        f2.write(new_line)
os.remove("小娃娃") # 删除源⽂文件
os.rename("小娃娃_new", "小娃娃") # 重命名新文件

第九章函数

今日内容

  • 函数定义
  • 函数调用
  • 函数返回值
  • 函数的参数

函数定义

# 通过定义一个计算数据长度的函数,def为关键字,count_len是函数名
def count_len():
    lst = [1, 2, 5]
    count = 0
    for i in lst:
        count += 1

# 通过函数名调用
count_len()

函数的返回值

def return_len():
    return 'len'

a = return_len()
print(a)

return:
# 1.return可以返回任意类型数据
# 2.返回多个内容是元组的形式
# 3.下方不执行,并且会终止当前这个函数
# 4.不写或者return后不写,都返回None

函数的参数

def yue(app1,app2,app3,app4):
    print(app1)
    print(app2)
    print(app3)
    print(app4)
yue('qq','weixin','taobao','zhifubao')

函数的参数:

  • 形参:定义的时候定义的参数

    位置参数: 一一对应 关键字参数: 按照名字进行传参 混合参数: 位置参数和关键字参数一起使用

  • 实参:实际传入的参数

    位置参数: 一一对应 关键字参数: 按照名字进行传参 混合参数: 位置参数和关键字参数一起使用

  • 传参:从调用函数的时候将值传递到定义函数的过程叫做传参

注意点

注意点: 参数名字不能重复,优先级不能放反
位置参数 >  默认参数
位置参数是一一对应
参数传递后,可以不使用
return 不能终止循环

三元运算符

c = a if a > b else b

条件成立的结果(a) 条件(if a > b else) 条件不成立的结果(b)

条件成立的结果 条件 条件不成立的结果

第十章函数进阶

今日内容

  • 函数的参数 动态参数
    • 动态接收位置参数
    • 动态接收关键字参数
  • 函数的注释
  • 名称空间
  • 函数的嵌套
  • global、nonlocal
    • global的宗旨
    • nonlocal宗旨

1.函数的参数 动态参数

动态接收位置参数:
# 动态位置参数
# def eat(*args):  # 函数的定义阶段 *聚合(打包)
#     print(args) # tuple
#     print(*args) # 函数体中的*表示打散(解包)
def eat(*args):
    pirnt('我想吃',args)
    
eat('大米饭', '米饭', '饭')
# 收到的结果是一个tuple元组
动态接收参数的时候:动态参数必须在位置参数后面
无论是否给*args值,它都是一个元组(),若不给值,就是()
def eat(a, b,*args):
    print("我想吃",args,a,b)

eat('大米饭','米饭','饭')
# 我想吃 ('饭',) 大米饭 米饭
# 默认参数放在最后边,通过关键字传参
def eat(a,b,*args,c='白菜'):
    print('我想吃',a,b,args,c)
eat('猪肉','粉条','豆腐','大葱')

结果:
我想吃 猪肉 粉条 ('豆腐', '大葱') 白菜 

注意: 形参的顺序: 位置参数 , 动态参数 , 默认参数

动态接收关键字参数:
def func(*args,**kwargs):
    print(args,kwargs)

lst = [1,23,5]
dic = {'k1':4, 'k2':5}
func(*lst,**kwargs)
func(1,23,5,k1=4,k2=5)

最终顺序:

  位置参数 > *args(动态位置参数) > 默认值参数 > **kwargs(动态默认参数)

总结
# 总结:
    # *args(聚合位置参数)      大家伙都用的名字, 可以进行修改但是不建议修改
    # **kwargs(聚合关键字参数) 大家伙都用的名字, 可以进行修改但是不建议修改

    # 函数的定义阶段 * 和 ** 都是聚合
    # 函数体中 * 就是打散, *args将元组中的元组进行打散  *kwargs将字典的键获取

    # 实参和函数体:
    #     * 打散
    #     ** 实参时能够使用

2.函数的注释

def func(a, b):
    """
    计算两数相加
    :param a:
    :param b:
    :return: a + b
    """
    return a + b
func(1, 10)

# print(a.__doc__)
# print(b.__doc__)  # 查看函数的注释
# print(a.__name__) # 查看函数的名字

3.名称空间

  • 内置空间:Python解释器自带的空间

  • 全局空间:py文件中顶格写的就是全局空间

  • 局部空间:函数中就是局部空间

    取值顺序:

    # 1.局部空间
    # 2.全局空间
    # 3.内置空间

    加载顺序:

    # 1.内置空间
    # 2.全局空间
    # 3.局部空间

4.函数的嵌套

不管在什么位置,只要是函数名()就是在调用一个函数

5.global、nonlocal

global : 只修改全局,如果全局没有就创建一个全局变量

nonlocal : 只修改局部,修改离nonlocal最近的一层,上一层没有继续向上上层查找.只限在局部

a = 10
def func():
    global a            # 声明之后,就可以对全局变量进行修改
    a += 1
    print(a)
func()

# nonlocal只能修改离nonlocal最近的一层,且不包括全局变量,如果没有就报错
def run():
    a = 19
    def func():
        print('123')
        def fun():
            nonlocal a
            a = 10
            print(a)
        fun()
run()

第十一章函数使用_迭代器

今日内容

函数名的第一类对象及使用

f-strings

迭代器

函数名的第一类对象及使用

  • 函数名可以当做值,赋值给变量
  • 函数名可以当做容器内的元素
  • 函数名可以当做函数的参数
  • 函数名可以当做函数的返回值

f-strings

f-strings
#     f"{变量名}"
#     F"{变量名}"
#     f"""{变量名}"""
#     f"{input()}"
#     f"{3 if 3>2 else 2}"
#     lst = [1,2,3,4,5]
#     f"{lst[4]}"
#     f"{lst[-1]}"
#     f"{dic['key1']}"

迭代器

可迭代对象:

只要具有__iter__()方法就是一个可迭代对象

迭代器:

具有__iter__()和__next__()两个方法才是迭代器

lst = [1, 2, 3, 4]
# l = iter(lst)             #变成迭代器,建议使用iter()
l = lst.__iter__()          # 将可迭代对象转换成迭代器
print(l.__nexr__())         # 获取一个值
print(l.__nexr__())         # 每一行获取一个值,当超过索引的时候会报错,并且只能从头到尾,不可逆

迭代器的优点

  • 惰性机制 ---节省空间

迭代器的缺点

  • 1.不能直接查看值,迭代器查看到的是一个迭代器的内存地址

  • 2.一次性,用完就没有了

  • 3.不能逆行

    时间换空间: 迭代器就是节省了空间,但是取值时间较长
    
    空间换时间: 容器存储大量的元素,取值时 取值时间短,但是容器占用空间较大
    
    迭代器是基于上一次停留的位置,进行取值
    
    可迭代对象:具有iter()方法就是一个可迭代对象
    
    迭代器:具有iter()和next()方法就是一个迭代器
for循环本质
# while True:
    #     try:
    #         print(l.__next__())
    #     except StopIteration:
    #         break
# 里面有一个捕捉异常的机制,所以取值不会超
python3和python2的区别:
# pyhton3:
    # iter()和 __iter__() 都有
    # next()和__next__()都有

# python2:
    # iter()
    # next()

第十二章内置_函数

今日内容

生成器

推导式

内置函数一

生成器

什么是生成器?生成器的本质就是一个迭代器

  • 迭代器是python自带的
  • 生成器是程序员自己写的一种迭代器

生成器编写方式:

  • 1.基于函数编写
  • 2.推导式方式编写
def func():
    print('这是一个函数')
    return '函数'
func()

def func():
    print("这是一个生成器")
    yield '生成器'

# 坑!!!,其实这个生成器只能执行一个next,因为只有一个yield
func()              # 生成一个生成器
print(func().__next__())        # 启动生成器
print(func().__next__())
# 上方这句代码的意思是:创建一个生成器并且执行一个next方法,两句一样但互不相干

函数体中出现yield代表要声明一个生成器

def func():
    msg = input("请输入内容")
    yield msg
    print("这是第二次启动")
    yield "生成器2"
    yield "生成器3"
    yield "生成器4"

g = func()
print(next(g))
print(next(g))
print(next(g))
print(next(g))      # 不能超过yield次数

yield和return的区别

相同点:

  • 都是返回内容
  • 都可以返回多次,但是return写多个只会执行一个

不同点:

  • return终止函数 yield是暂停生成器
  • yield能够记录当前执行位置

一个yield对应一个next

生成器的作用

# 生成器的作用是节省空间

# 可迭代对象:
#   优点: list,tuple,str 节省时间,取值方便,使用灵活(具有自己私有方法)
#   缺点: 大量消耗内存

# 迭代器:
#   优点:节省空间
#   缺点:不能直接查看值,使用不灵活,消耗时间,一次性,不可逆行

# 生成器:
#   优点:节省空间,人为定义
#   缺点:不能直接查看值,消耗时间,一次性,不可逆行

# 使用场景:
# 1.当文件或容器中数据量较大时,建议使用生成器

# 数据类型 (pyhton3: range() | python2 :xrange()) 都是可迭代对象 __iter__()
# 文件句柄是迭代器  __iter__() __next__()

没有send方法就是一个迭代器,具有send方法的就是一个生成器
def func():
    lst = [1,2,3,45,6]
    lst1 = ["alex","wusir","taibi","baoyuan"]
    yield from lst
    yield from lst1
# yield 将可迭代对象一次性返回
# yield from 将可迭代对象逐个返回

g = func()

for i in g:
    print(i)

推导式

列表推导式:

普通循环
print([i for i in range(10)])
print([变量 for循环])

筛选
lst = []
print([i for i in range(10) if i % 2 == 0])
print([i for i in range(10) if i > 2])
[操作后的变量 for循环 判断操作]

集合推导式:

普通循环
print({i for i in range(10)})
{变量 for循环}
筛选
print({i for i in range(10) if i % 2 == 1})
{操作后的变量 for循环 操作}

字典推导式:

普通循环
print({i: i+1 for i in range(10)})
{键:值 for循环}
筛选模式
print({i:i+1 for i in range(10) if i % 2 == 0})
{操作的键:值 for循环 操作}

生成器推导式:

普通模式
tu = (i for i in range(10))
(变量 for循环)
筛选模式
tu = (i for i in range(10) if i > 5)
(操作后的变量 for循环 操作)

内置函数一

all()       判断容器中的元素是否都为真
any()       判断容器中的元素是否有一个为真
bytes()     将字符串进行编码
callable()  查看对象是否可  调用 == ()
chr()       通过表位序号查找元素
complex()   复数
eval()      神器一
exec()      神器二 神器禁止使用
frozenset() 冻结集合
globals()   查看全局空间变量
hash()      区分可变数据类型和不可变数据类型
help()      查看帮助信息
id()        查看内存地址
locals()    查看当前空间变量
oct()       十进制转八进制
ord()       通过元素获取当前unicode表位的序号
pow()       幂,两个参数是求幂,三个参数时求幂后在取余
repr()      查看数据的原生态
round()     保留小数位
divmod()    求商和余
bin()       十进制转二进制

第十三章

今日内容

  • 匿名函数
  • 内置函数二
  • 闭包

匿名函数

匿名函数就是一行函数,关键字是lambda

lambda x:x
# lambda 参数:返回值
x 是普通函数的形参  可以不定义形参
:x 是 普通函数的返回值(只能返回一个数据类型)
    
f = lambda x:x+6
print(f(1))                 # 结果:7
print(f.__name__)           # 查看函数的名字  函数名为lambda

lst = [lambda :i for i in rang(5)]
print(lst[0]())


# 结果:4
面试题拆解:
lst = []
for i in range(5):
    def func():
        return i
    lst.append(func)

内置函数二

字典的合成方式

dict([(1,2),(3,4)])             # 中括号也可以换成小括号
# {1: 2, 3: 4}

dict(k=1,v=2,c=3)
# {'k': 1, 'v': 2, 'c': 3}

dic1 = {"key1":1,"key2":2}
dic2 = {"a":1,"b":2}
print(dict(**dic1,**dic2))
# {'key1': 1, 'key2': 2, 'a': 1, 'b': 2}

print()

sep:每个元素之间分割的字符,默认是" "空格
end:print执行完后的结束语句,默认是\n
file:文件句柄,默认是显示到屏幕,也可以写进文件,例如:
print(1,2,3,4,file=open("test","w",encoding="utf-8"))

sum

算出可迭代对象中的和,只能算int

abs

绝对值

dir

print(dir(list))
print(dir(str))
# 查看当前对象所有方法,返回的是列表

zip

拉链
lst1 = [1,2,3,4]
lst2 = ['a','b','c','d','e']

面试题:
print(dict(zip(lst1,lst2)))
# {1: 'a', 2: 'b', 3: 'c', 4: 'd'}

format

print(format('alex','>20'))     # 左对齐
print(format('alex','<20'))     # 右对齐
print(format('alex','^20'))     # 居中

进制转换
print(format(10, "b"))      # bin  二进制
print(format(10, "08o"))    # oct 八进制
print(format(10, "08x"))    # hex 十六进制
print(format(0b1010), "d")  # 十进制

reversed

反转
print(list(reversed("alex")))
# 得到的是迭代成列表之后的反转
# 得到的是一个新列表

filter

过滤
lst = [1,2,3,4,5,6]
print(list(filter(lambda x:x>1,lst)))
# 过滤掉大于1的数字

lst = [{'id':1,'name':'alex','age':18},
        {'id':1,'name':'wusir','age':17},
        {'id':1,'name':'taibai','age':16},]

print(list(filter(lambda x:x['age']>16,lst)))
# 留下年龄大于16的信息

map

映射函数(将可迭代对象中的每个元素执行指定的函数)
print(list(map(lambda x,y:x+y,[1,2,3],[11,22,33,44])))
# 将每个列表的对应元素相加

print([i*8 for i in [1,2,3,4]])
# 8,16,24,32

sorted

print(sorted([1,-22,3,4,5,6],key=abs))  # key指定排序规则
# 排序 执行了绝对值之后的列表

lst = ["三国演义","红楼梦","铁道游击队","西游记","水浒传","活着"]
print(sorted(lst,key=len))
# 通过长度排序

lst = [{"age": 19}, {"age1": 20}, {"age2": 80}, {"age3": 10}]
# print(sorted(lst, key=lambda x: x.values()))
print(sorted(lst, key=lambda x: x.keys(), reverse=True))
# 通过键和值排序

max,min

最大值和最小值

reduce

from functools import reduce   # 累计算

# 内部实现原理
def func(x,y):
    return x+y
print(reduce(func,[1,2,3,4,5]))

print(reduce(lambda x,y:x+y,[1,2,3,4,5]))

闭包

闭包
# 1.在嵌套函数中,使用非本层且非全局变量的就是闭包
# print(inner.__closure__)  判断是否是闭包  返回None就不是
  
# 闭包的作用:
    # 1.保护数据的安全性
    # 2.装饰器

第十四章装饰器

装饰器

# 开放封闭原则
- 1.对扩展是开放的
- 2.对修改是封闭的

# 在不修改源代码和调用方式的情况下,对函数进行扩展
# 第一版装饰器
def times(func):
    def foo():
        print('装饰001')
        func()
        print('装饰002')
    return foo

def func1():
    print("今天是个好日子1")

func1 = times(func1)
func1()
# python内置的语法糖
# 要将语法糖放在被装饰的函数正上方
def times(func):
    def foo():
        print('装饰001')
        func()
        print('装饰002')

    return foo

@times
def func1():                # func1 = times(func1)
    print("被装饰的函数1")

@times
def func2():                # func2 = times(func2)
    print("被装饰的函数2")

func1()
# 有参数的函数语法糖
def func(func):

    def foo(*args, **kwargs):
        print('装饰001')
        func(*args, **kwargs)
        print('装饰002')
    return foo


@func
def func1(*args, **kwargs):
    print(args,kwargs)
    print('被装饰的函数1')


@func
def func2(*args, **kwargs):
    print(args,kwargs)
    print('被装饰的函数2')


func2(5)
# 要求
#博客园登陆之后有几个页面,diary,comment,home,如果我要访问这几个页面,必须验证我是否已登录。 如果已经#成功登录,那么这几个页面我都可以无阻力访问。如果没有登录,任何一个页面都不可以访问,我必须先登录,登录成功#之后,才可以访问这个页面。

user_status = {
    'user_name': None,
    'user_status': False

}


def auth(func):

    def foo():
        if user_status['user_status']:
            ret = func()
            return ret

        user_name = input('name:')
        user_pwd = input('pwd:')
        if user_name == 'xuhuo' and user_pwd == '123456':
            user_status['user_status'] = True
            ret = func()
            return ret
    return foo


@auth
def zhu_ye():
    print('欢迎来到博客园主页。')


@auth
def dirary():
    print('欢迎来到博客园的日记页面。')


@auth
def ping_lun():
    print('欢迎来到评论页面。')


@auth
def sui_bi():
    print('欢迎来到随笔页面。')


zhu_ye()
sui_bi()
dirary()
ping_lun()

第十五章装饰器_递归

今日内容

带参数装饰器

多个装饰器修饰一个函数

递归

带参数的装饰器

# 判断argv,当登录不同的网页,会有不同的装饰效果
def auth(argv):
    def warpper(func):
        def inner():
            if argv == '博客园':
                func()
            elif argv == '码云':
                func()

        return inner

    return warpper


@auth('博客园')
def home_page0():
    print('欢迎来到博客园主页')


@auth('码云')
def home_page1():
    print('欢迎来到码云主页')


home_page0()
home_page1(

多个装饰器修饰一个函数

# 多个函数装饰一个函数时,先执行离被装饰函数最近的装饰器
def auth(func):         # wrapper1装饰器里的 inner
    def inner(*args,**kwargs):
        print("额外增加了一道 锅包肉")
        func(*args,**kwargs)
        print("锅包肉 38元")
    return inner

def wrapper1(func):      # warpper2装饰器里的 inner
    def inner(*args,**kwargs):
        print("额外增加了一道 日魔刺生")
        func(*args,**kwargs)
        print("日魔刺生 白吃")
    return inner

def wrapper2(func):         # 被装饰的函数foo
    def inner(*args,**kwargs):
        print("额外增加了一道 麻辣三哥")
        func(*args,**kwargs)
        print("难以下嘴")
    return inner

@auth        # 1           7
@wrapper1    #   2       6
@wrapper2    #    3    5
def foo():   #      4
    print("这是一个元宝虾饭店")

foo()

递归

递归
1.不断调用自己本身
2.有明确的终止条件
递归的最大深度,官方说明是1000,实际测试是994/997/998

# 循环一个列表,打印出每一个元素
li = [1, 3, 4, "alex", [3, 7, 8, "TaiBai"], 5, "RiTiAn",[4,5,6,[7,[11,12,34,5],10,8,9]]]
def func(lst):
    for i in lst:
        if type(i) == list:
            func(i)
        else:
            print(i)
func(li)

第十六章模块

今日内容

  • 自定义模块
  • time模块
  • datetime模块
  • rendom模块

自定义模块

# import 模块         例:import time
# 导入的是time模块中所有的内容(变量,函数名,类名等)
# import做的三件事:
1.将文件中的所有代码读取到当前文件
2.当前文件开辟空间
3.等待被调用

# 被导入模块有独立的名称空间,定义模块中得全局变量不会产生冲突
示例:
# module_one.py
name = 'xuhuo'
def func():
    print("这是第一个模块中的函数")
    
# module_two.py
import module_one
name = 'xuyuwei'
def func():
    print('这是第二个模块的函数')
func()
module_one.func()

模块二的执行的结果:
这是第二个模块的函数
这是第一个模块中的函数

# 为模块起别名
import time as f
通过 f.name 调用   f.变量或者函数

# 导入多个模块时写法
import os
import sys
import json
# from...import..
# 自己写模块module_one 和 module_two
# module_one中导入module_two模块中的func函数
from module_two import func()

from和import的对比,from直接把导入的函数或变量直接放在当前的名称空间中。所以在当前名称空间中,直接使用名字就可以了,无需加前缀

好处:使用更方便
坏处:容易和当前执行文件中的名字冲突
# 当执行文件与模块同名的变量或者函数名,会有覆盖效果

from datetime imoirt datetime as date
d = date.now()          # 获取当前时间

# 一行可导入多个
__all__=['name','read1'] 
#这样在另外一个文件中用from spam import *就这能导入列表中规定的两个名字

py文件的两种功能

1.脚本,一个文件就是整个程序(例如博客园登录作业等)
2.模块,文件中存放着一堆功能,用来导入使用

if __name__ == '__main__':
    func()
    print(name)
# 当被导入其他文件时不执行,只有自己运行时,才运行的调试代码,不被导入
# 用来控制.py文件在不同的应用场景下执行不用的逻辑(或者是在模块文件中测试代码)

模块的搜索路径

# 内存中已经加载的模块->内置模块->sys.path路径中包含的模块

#1.在第一次导入某个模块时(比如meet),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用(ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看)

#2.如果没有,解释器则会查找同名的内置模块

#3.如果还没有找到就从sys.path给出的目录列表中依次寻找meet.py文件。

time模块

import time
# 这是一个时间模块,通常用于获取当前时间或时间戳等等

1.时间戳:时间戳表示的是格林尼治时间是从1970年1月1日00:00:00开始按秒计算的偏移量,每一刻都在变化(返回的是float类型)
2.格式化时间,格式化的时间字符串(1999-12-06)
python中时间日期格式化符号: 
%y 两位数的年份表示(00-99) 
%Y 四位数的年份表示(000-9999) 
%m 月份(01-12) 
%d 月内中的一天(0-31) 
%H 24小时制小时数(0-23) 
%I 12小时制小时数(01-12) 
%M 分钟数(00=59) 
%S 秒(00-59) 
%a 本地简化星期名称 
%A 本地完整星期名称 
%b 本地简化的月份名称 
%B 本地完整的月份名称 
%c 本地相应的日期表示和时间表示 
%j 年内的一天(001-366) 
%p 本地A.M.或P.M.的等价符 
%U 一年中的星期数(00-53)星期天为星期的开始 
%w 星期(0-6),星期天为星期的开始 
%W 一年中的星期数(00-53)星期一为星期的开始 
%x 本地相应的日期表示 
%X 本地相应的时间表示 
%Z 当前时区的名称 
%% %号本身
结构化时间元组(struct_time)元组共有9个元素(年,月,日,时,分,秒,一年中的第几周,一年中第几等)
import time

# 获取当前时间戳
print(time.time())

# 将时间戳转换成结构化时间,元组形式
print(time.localtime(time.time()))

# 将结构化时间转换成字符串
time_t = time.localtime()
print(time.strftime('%Y-%m-%d %H:%M:%S', time_t))

# 休眠,单位秒
time.sleep(3)

# 将字符串转换成结构化时间
str_time = "2019-8-22 10:11:22"
time_g = time.strptime(str_time, "%Y-%m-%d %H:%M:%S")
print(time_g)

# 将结构化时间转换成时间戳
print(time.mktime(time.localtime()))
# 总结:
# time.time() 时间戳
# time.sleep() 睡眠
# time.localtime() 时间戳转结构化
# time.strftime() 结构化转字符串
# time.strptime() 字符串转结构化
# time.mktime() 结构化转时间戳
# %Y 年
# %m 月
# %d 日
# %H 时间
# %M 分钟
# %S 秒

datetime

from datetime import datetime,timedelta

# print(datetime.now())  # 获取当前时间

# 算两个时间差几天几个小时几分钟,自己指定时间
# print(datetime(2018,10,1,10,11,12) - datetime(2011,11,1,20,10,10))

# 将对象转换成时间戳
# d = datetime.now()
# print(d.timestamp())

# 将时间戳转换成显示的时间对象
# f_t = time.time()
# print(datetime.fromtimestamp(f_t))

#将对象转换成字符串
# d = datetime.now()
# print(d.strftime("%Y-%m-%d %H:%M:%S"))

# 将字符串转换成对象
# s = "2018-12-31 10:11:12"
# print(datetime.strptime(s,"%Y-%m-%d %H:%M:%S"))

# 可以进行加减运算
# from datetime import datetime,timedelta

# 减去一天
# print(datetime.now() - timedelta(days=1))

# 减去一个小时
# print(datetime.now() - timedelta(hours=1))

random模块

import random

# 随机产生一个1-50之间的整数,包括1
print(random.randint(1,50))

# 随机产生一个0-1之间的随机小数,不包括1
print(random.randon())

# 1-10之间随机小数,不包括10
print(random.uniform(1, 10))

# 从容器中随机选择一个,参数是可迭代类型
print(random.choice((1,2,6,7,9,8)))

# 从容器中随机生成n个元素,以列表的形式返回,会出现重复元素
print(random.choices((1,7,8,6,5,48,94,43,16),k = n))

# 从容器中随机选择n个元素,以列表的形式返回,不会出现重复元素
print(random.sample((1,7,8,9,4,3,78,89,45,56),k=n)

# 随机奇数或随机的偶数
print(random.randrange(1,10,2))

lst = [1,8,9,7,45,76]
random.shuffle(lst)
# 洗牌,将有序的数据打散
print(lst)

第十七章软件开发规范_模块

今日内容

  • 软件开发规范
  • OS
  • sys

软件开发规范

目录结构
bolg项目名字
    bin启动文件
        starts.py   
    conf配置文件
        setting.py  
    log日志文件
        logg.log
    db数据文件
        register
    lib公共组件
        common.py
    core主逻辑文件
        src.py
        src1.py

OS模块

import os   # os是和操作系统做交互,给操作发指令
print(os.getcwd())      # 获取当前文件工作的路径

os.chdir("F:\Python全栈\S25")   # 路径切换
print(os.getcwd())              # 获取当前文件工作的路径
print(os.curdir)                # 返回当前目录:('.')
print(os.pardir)                # 获取当前目录的父目录字符串名('..')

# 文件夹
# os.mkdir('a2')            # 创建文件夹
# os.rmdir('a2')            # 删除文件夹
# os.makedirs('a1/a2/a3')   # 递归创建文件夹
# os.removedirs('a1/a2')    #递归删除文件夹
print(os.listdir(r'F:\Python全栈\S25\day17模块'))   #查看当前文件下的所有内容

# 文件
# os.remove(r'F:\Python全栈\S25\day17模块\a2') # 删除文件
# os.rename('a2','a1')              # 重命名

# 路径
# 返回文件的绝对路径:
# print(os.path.abspath('a1'))
# 将路径分割成一个路径和一个文件名,返回元组,路径和文件名:
# print(os.path.split(r'F:\Python全栈\S25\day17模块'))
# 获取父目录:
# print(os.path.dirname('F:\Python全栈\S25\day17模块'))
# 获取文件名:
# print(os.path.basename('F:\Python全栈\S25\day17模块'))
# 路径拼接:
print(os.path.join('F:\Python全栈','S25\day17模块','模块测试'))

# 判断
# print(os.listdir())           # 展示当前文件的所有文件
# 判断当前路径是否存在:
# print(os.path.exists(r'F:\Python全栈\S25\day17模块\blog'))
# 判断是不是绝对路径:
# print(os.path.isabs(r'F:\Python全栈\S25\day17模块\blog'))
# 判断是不是文件夹:
# print(os.path.isdir(r'F:\Python全栈\S25\day17模块\blog'))
# 判断是不是文件:
# print(os.path.isfile(r'F:\Python全栈\S25\day17模块\blog'))

# 获取文件或文件大小:
print(os.path.getsize(r'F:\Python全栈\S25\day17模块\a1'))
print(os.path.getsize(r'F:\Python全栈\S25\day17模块\blog'))

sys模块

import sys      # sys和python解释器做交互
print(sys.path)         # 模块查找的顺序
print(sys.argv)         # 只能在终端执行
print(sys.modules)      #查看加载到内存的模块
print(sys.platform)     #查看当前操作系统平台
print(sys.version)      # 查看当前解释器的版本

序列化模块

import json
import pickle

#json模块 :(重点)
1.不同语言都遵循的一种数据转化格式,即不同语言都使用的特殊字符串。(比如Python的一个列表[1, 2, 3]利用json转化成特殊的字符串,然后在编码成bytes发送给php的开发者,php的开发者就可以解码成特殊的字符串,然后在反解成原数组(列表): [1, 2, 3])
2.json序列化只支持部分Python数据结构:dict,list, tuple,str,int,float,True,False,None
tuple序列化之后是列表的形式

# pickle模块:
只能是Python语言遵循的一种数据转化格式,只能在python语言中使用。
支持Python所有的数据类型包括实例化对象。
import json
dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = json.dumps(dic)       # 将字典转化成字符串
print(str_dic, type(str_dic))   

# 将字符串的字典转化成字典
d = json.loads(str_dic)         # 用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(d, type(d))


# 列表之间的转化
lst = [1, 8, 7, 9, 4, 3, 84, 95, 35, 75, 86, 94, 81]
lst1 = json.dumps(lst)
print(lst1, type(lst1))

lst2 = json.loads(lst1)
print(lst2, type(lst2))
# 将字典写入到文件中,然后读取出来
dic = {'key': 'v1'}
json.dump(dic, open('a1', 'a', encoding='utf-8'))
print(json.load(open('a1', 'r', encoding='utf-8')))
# json序列化存储多个数据到一个文件中是有问题的,默认一个json文件只能才能存储一个json数据,但是可以解决
dic = {"key": "v1"}
f = open("a", "a", encoding="utf-8")
f.write(json.dumps(dic) + "\n")
f.write(json.dumps(dic) + "\n")
f.write(json.dumps(dic) + "\n")
f.write(json.dumps(dic) + "\n")
f.close()

f1 = open("a", "r", encoding="utf-8")
for i in f1:
    print(json.loads(i), type(json.loads(i)))

f.close()

pickle

# pickle模块是将Python所有的数据结构以及对象等转化成bytes类型,然后还可以反序列化还原回去。
# 只有python中有,几乎可以序列python中所有数据类型,匿名函数不能序列
import pickle
def func():
    print(1)
a = pickle.dumps(func)      # 将源数据类型转换成类似字节的内容
print(pickle.loads(a))      # 将类似字节的内容转换成源数据类型

猜你喜欢

转载自www.cnblogs.com/bky20061005/p/12544304.html