python基础篇

Posted tian-cai-1996

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python基础篇相关的知识,希望对你有一定的参考价值。

python入门

  1. python历史

    • python2和python3的区别

      python2的源码不统一,出现重复代码

      python3统一了源码,不会出现重复代码

    • python是什么编程语言

      python是一款解释性语言,具有开发效率高的优点,缺点是运行速度慢

    • python的种类

      • cpython官方

      • jython java编写

      • ironpython .net

      • pypy python 可以提高运行速度

  2. 变量

    • 变量的命名规则

      • 变量名由字母,数字_下划线组成

      • 不能使用python的关键字

      • 不能以数字开头

      • 不能使用拼音和汉字

      • 注意区分大小写

      • 变量名要具有可描述性,可辨识性

      • 驼峰式命名(推荐下划线的方式)

    • 一个变量名在一个内存中,只可能存在一个

  3. 常量

    • python中没有常量的概念,以变量名全部大写来识别

  4. 注释

    # 代表单行注释
    ‘‘‘ ‘‘‘或者""" """代表多行注释也可以包裹多行字符串
  5. 基础数据类型

    • int类型

      int数字类型,一般用来计算和比较

    • str字符串类型

      字母数字汉字都可以作为字符串必须用引号包裹起来

    • bool类型

      True为真或者1

      False为假或者0

输入输出

  • 输出print

    print(‘helloworld‘)
  • 输入input(用户交互程序)

    name=input(‘请输入姓名:‘)
    print(type(name))#字符串
    #input所接收获取到的内容都是字符串

if流程控制语句**

  • if else 二选一

  • if elif elif 多个选择一个或者零个

  • if elif elif else 多个选一个

  • if if if 多选多或零

  • if 嵌套 进行多层判断 一般if嵌套写三层就可以了

    • if 嵌套 进行多层判断 一般if嵌套写三层就可以了

    # 用来代表单行注释
    """
    多行注释
    多行注释
    多行注释
    多行注释
    多行注释
    """
    # print输出
    print(‘hello world‘)
    # input输入,可以赋值给变量
    name = input(‘请输入‘)
    print(name)
    # input输入为字符串格式,想要输出其他类型,要进行格式转换
    age = int(input(‘输入:‘))
    print(type(age))
    # 常量,python常量用大写的变量名来表示
    LUCKY = ‘luckycoffee‘
    # 字符串拼接,字符串只能和字符串相加
    a = ‘lijie‘
    b = ‘guobaoyuan‘
    print(a + b)
    # 字符串相乘
    print(a * 3)
    # if elif else流程判断
    # 需求,编写一个用户交互程序
    name2 = input(‘亲输入用户名:‘)
    age = int(input(‘亲输入年龄:‘))
    sex = input(‘亲输入性别:‘)
    if name2 == ‘王五‘ and age > 25 and sex == ‘男‘:
       print(‘可以去城中村洗脚了‘)
       if 50 > age > 35:
           print(‘还是回家歇着吧‘)
       elif 35 > age > 25:
           print(‘小心腰‘)
       else:
           print(‘年少轻狂‘)
    elif name2 == ‘王五‘ and 18 < age < 25 and sex == ‘女‘:
       print(‘洗脚很挣钱‘)
    else:
       print(‘你是个?‘)

     

     

    while循环

    1. while循环条件控制

      sam=1
      while sam<10:#
         print(sam)
         sam=sam+1

       

    2. while循环break终止循环

      sum=1
      while True:
         if sum == 10:
             break
         print(sum)
         sum=sum+1

       

    3. while循环continue跳出本次循环

      sum1 = 1
      while sum1<10:
         if sum1 ==8:
             sum1=sum1+1
             continue
         print(sum1)
         sum1=sum1+1
    4. while else循环

      sum = int(input(‘请选择输入0或1:‘))
      while sum == True:
         name = input(‘亲输入用户名:‘)
         pwd = input(‘亲输入密码‘)
         if name == ‘lijie‘ and pwd == ‘123456‘:
             print(‘登陆成功‘)
             break
         else:
             print(‘用户名或密码错误‘)
      else:
         print(‘退出成功‘)

    for循环

    1. for循环基本结构

      for+空格+in+可迭代对象+冒号(#整型和布尔值不能进行循环)
      缩进 循环体
      for i in ‘asdf‘:#i是变量名
         pass#pass和...是占位符
      print(i)#当在外围打印i时,值应该是for循环变量最后所获得的值

    格式化输出

    1. %s%d格式化输出

      name=‘lijie‘
      age=23 #在格式化的时候想要使用%可以用%%进行转义
      print((‘姓名:%s,年龄:%d‘)%(name,age))

       

    2. format格式化输出

      • 通过顺序来传递参数

        print((‘{1},{0},{1}‘).format(‘boy‘,‘girl‘))
      • 通过变量名来传递参数

        print((‘{name}:{url}‘).format(name=‘python‘,url=‘www.python.org‘))

         

      • 通过字典来传递参数

        dict={‘name‘:‘boy‘,‘sex‘:‘男‘}
        print((‘{name},{sex}‘).format(**dict))

         

      • 通过列表来传递参数

        list=[‘boy‘,‘男‘,‘25‘]
        list1=[‘哈哈‘,‘呵呵‘]
        print((‘{0[0]},{0[1]},{0[1]}‘).format(list,list1)

         

    3. python3.6以上新增f方法

      name=‘lijie‘
      age=3
      s=f‘姓名:{name},年龄:{age}‘
      print(s)

    编码初识

    • ascii 不支持中文

    • gbk 中文2个字节,英文1个字节

    • unicode 中文4个字节,英文2个字节

    • utf-8 中文3个字节,欧洲2个字节,英文1个字节

    • # 编码:将文字转换成字节形式  encode
      # 解码:将字节转换成文字形式 decode

    运算符

    比较运算符> < >= <= == !=
    赋值运算符 += -= *= /= //= **= %=
    成员运算符 in not in
    逻辑运算符 and or not
    算法运算符 + - * / ** % //

    位运算符

    下表中变量 a 60,b 13,二进制格式如下
    a = 0011 1100
    b = 0000 1101
    -----------------
    a&b = 0000 1100
    a|b = 0011 1101
    a^b = 0011 0001
    ~a = 1100 0011
    ------------------------
    #&
    按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0
    (a & b) 输出结果 12 ,二进制解释: 0000 1100
    #|
    按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。
    (a | b) 输出结果 61 ,二进制解释: 0011 1101
    #^
    按位异或运算符:当两对应的二进位相异时,结果为1
    (a ^ b) 输出结果 49 ,二进制解释: 0011 0001
    #~
    按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 ~x 类似于 -x-1
    (~a ) 输出结果 -61 ,二进制解释: 1100 0011,在一个有符号二进制数的补码形式
    #<<
    左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0。
    a << 2 输出结果 240 ,二进制解释: 1111 0000
    #>>
    右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数
    a >> 2 输出结果 15 ,二进制解释: 0000 1111

     

    python数据类型

    1. 数据类型转换

      str转换int

      a=int(‘33‘)
      print(a)#结果33#只有要转换的字符串是数字的时候才能转换
      ?

      int转换str

      n=str(56)
      print(n)#结果"56"
      ?

      bool转换str

      bool值不为空就是True,空就是False
      b=str(True)
      print(b)#结果true
      ?

      bool转换int

      b=int(True)
      print(b)#结果1
      ?

    进制转换

    • 十进制转换二进制

      bin(23)#十进制转换二进制
      十进制转换由下往上数
    • 二进制转换十进制

      int(‘1011‘,2)#要转换的十进制要用引号引起来,从右往左数
    • 八进制转换十进制

      # 八进制转换成十进制
      v3 = "011"
      print(int(v3))
      # 11
    • 十进制转换八进制

      # 十进制转换成八进制:---> oct
      v4 = 30
      print(oct(int(v4)))
      # 0o36
    • 十六进制转换十进制

      # 十六进制转换成十进制:
      v5 = "0x12"
      print(int(v5,16))
      # 18
    • 十进制转换十六进制

      # 十进制转换成十六进制:---> hex
      v6 = 87
      print(hex(int(v6)))
      # 0x57
    • format进制转换

      print(format(13,">20"))  # 右对齐
      print(format(13,"<20"))  # 左对齐
      print(format(13,"^20"))  # 居中
      ?
      print(format(13,"08b"))    # 2
      print(format(13,"08d"))    # 10
      print(format(13,"08o"))    # 8
      print(format(12,"08x"))    # 16

       

    1. str字符串类型

      • 字符串切片

        # name = "今天是个好日子"
              # 0 1 2 3 4 5 6
              #-7-6-5-4-3-2-1
        # a = name[0]
        # b = name[1]
        # print(a+b)
        # 切片
        # print(name[0:2]) # 顾头不顾尾 name[起始位置:终止位置]
        # print(name[:]) # 某个位置不指定的时候默认取最后或最前
        # print(name[2:5])
        # print(name[-2:-5])
        # print(name[-2:-5:-1]) # [起始位置:终止位置:步长] 步长默认为1
        ?
      • 字符串方法

        upper()#将字符串全部大写
        lower()#将字符串全部小写
        startswith()#判断以什么开头,可以指定范围
        endswith()#判断以什么结尾,可以指定范围
        strip()#去除空格换行制表符,可以指定去除的字符
        replace()#替换,可以指定次数
        isalnum()#判断是不是数字字母汉字组成
        isdigit()#判断是不是阿拉伯数字
        isalpha()#判断是不是字母和汉字
        isdecimal()#判断是不是十进制
        len()#获取字符串的长度
        split()#以空格换行制表符分割,可以指定分割符和次数
        rsplit()
        #从右边开始分割
        count()#获取字符出现的次数
        find()#查找字符在字符串中出现的次数,可以指定开始与结束,有返回索引,否则返回-1
        index()#与find一样,但是如果找不到就报错
        capitalize()#把字符串的首字母大写
        ‘_‘.join(s)#使用指定的字符吧字符串的每个字符分割
        casefold()#与lower一样,但是lower只对ascii由效
        format()#格式化输出,用{}表示
        center()#返回字符串居中,空格填充的指定长度的字符串
        decode()#以指定的编码格式进行解码
        encode()#以指定格式进行编码,二进制
        expandtabs()#将字符串中的tab键转换成空格,默认为8个
        isidentifier()#判断是不是有效的puthon标识符
        isspace()#判断字符串中是不是值只包含空格
        isnumeric()#判读字符串是不是只包含数字字符
        isprinttable()#判断是不是都是可打印的字符或字符串,可以用来查看是不是包含转义符
        ljust()#与center相似,字符串左对齐,空格补充至指定长度
        rjust()#与ljust相反
        partition()#与split相似,但是分割后分割字符保留,返回三元字符串
        splitlines()#以换行符进行分割,返回分割后的列表
        swapcase()#对字符串中的大小写进行反转

        1. 列表

          • 列表的表现形式是[ ]的形式:lst=[‘你好‘,‘哈哈‘]

          • 列表是一个有序的,可变的数据类型,支持多种数据类型

          • 列表的增删改查

            #增
            lst.append(‘哈哈‘)#在列表最后添加一位
            lst.insert(0,‘啊啊‘)#指定索引添加,后面的元素后移
            lst.extend(‘今天下雨了‘)#将字符串的每个元素分别添加到列表中,迭代增加
            #删
            lst.pop(0)#默认删除最后一位,可以指定索引删除,删除后讲删除的值返回,
            lst.remove(‘哈哈‘)#指定元素删除,在有重命名的情况下,删除一个
            lst.clear()#清除
            del list[0] del list[0:5:2]#看可以使用下标,步长进行删除
            #改
            list[0]=‘呵呵‘#通过赋值直接更改
            list[0:3]=‘1232456‘#元素可以超出切片的位数
            list[0:4:2]=‘12‘#元素与位置一一对应,不能多也不能少
            #查
            for i in lst:
               print(i)#用for循环遍历
            count()#次数
            sort(rever=False)#排序
            reverce()#反转
            ?
          • 列表的嵌套

            lst=[‘你好‘,[‘哈哈‘,[‘呵呵‘]]#可以通过索引切片一层一层查找
        2. 元祖

          • 元祖的表现形式是( )的形式:tu=(‘你好‘,‘哈哈‘)

          • 元祖是不可变的,用来存储一些重要数据

          • 可以通过切片,索引和for循环来查找,不能增删改

        3. range

          • range的特性是顾头不顾尾

          • python2和python3中的区别

            print(range(0,10))
            #python2中直接返回列表,xrange()和python3中的range相似
            #python3中作为迭代对象,怎么写就怎么打印,可以使用list()进行转换
            ?
          • range的语法

            range(0,10)#起始位置和终止位置,起始位置是0时可以默认不写
            range(10,1,-1)#也可以从大到小生成数据,
            range(1,100,2)#也可以用来生成奇数和偶数等
            ?
          • 常见的问题

            # lst = []
            # for i in lst:
            #     lst.append("alex")
            #     print(lst) # 不会打印内容 因为lst是空的
            ?
            # lst = [1,2]
            # for i in lst:
            #     lst.append("alex")
            #     print(lst) # 循环打印lst中的内容 -- 此循环是死循环
            ?
            # lst = [1,2]
            # for i in lst:
            #     lst.append("alex")
            # print(lst) # 死循环 -- 不会打印内容
            ?
            # lst = []
            # for i in range(5):
            #     lst.append([])
            # print(lst) # [[],[],[],[],[]]
            ?
            # lst = [1,2]
            # lst[0] = lst
            # print(lst) # [[...],2]
            ?

             

        4. 字典

          • 字典是可变的,无序的

          • 字典是由键值对构成,键必须是不可变的数据类型且唯一,值可以是任意类型

          • 字典的增,删,改,查

            #增加
            dic[‘name‘]=‘哈哈‘#暴力添加
            dic,setdefault(‘age‘,18)#不存在就添加,存在就不添加
            #删除
            dic.pop(‘name‘)#通过键来删除键值对,返回值:返回的是被删除的值
            del dic[‘name‘]#通过键来删除键值对
            dic,clear()#清空
            修改
            dic[‘name‘]=‘呵呵‘#暴力修改
            dic.update({‘name‘:‘卡卡卡‘})#update括号内部的字典高于前面的字典
            查找
            for i in dic:#获取的是所有的键
            dic.get(‘name‘)#通过get方法和键,来获取值,存在就返回,不存在就是空
            ?
            #其他操作
            dic.keys()#获取所有的键,是一个高仿列表,可以遍历,不可下标
            dic.values()#获取所有的值,是一个高仿列表,可以遍历,不可下标
            dic.items()#返回所有的键值,返回的是一个列表,键值对是元祖形式
            diat=dic.fromkeys(‘123456‘,[2])#批量添加,值会共用
            dic.popitem()#随机删除#3.6史默认删除最后一个
            ?
          • 解构

            a,b = 10,12
            print(a)
            print(b)
          • 10,12
            ?
            a = 10
            b = 20
            a,b = b,a
            print(a,b)
          • 20,10
            ?
            a,b = [1,2]
            print(a,b)
            1,2?

          • a,b = (3,4)
            print(a,b)
          • 3,4
            ?
            a,_,b = (3,4,5)
            print(a,b)   # 等号后边的值和前面的变量名要一一对应
          • 3,5
            ?
            a = 10,12  # 本质就是一个元组
            print(a)
          • (10,12)
            ?
            a,b = "23"
            print(a,b)
          • 2,3
            ?
            a,b = {"1":"a","2":"b"}
            print(a,b)
          • 1,2
            ?
            for i in dic1.items():
               print(i)
            ?
            for k,v in dic1.items():
               print(k,v)    # 获取每个元素的键和值
            ?
            ?
          • 字典的嵌套

            dic = {1001:["周杰伦","林俊杰"],
                  1002:{"汪峰":{"前妻1":["大烧饼"],"前妻2":["熊大","熊二"],"国际章":"肉丝"}},
                  1003:{"陈冠希":["阿娇","阿萨","张柏芝"]},
                  1004:{"韦小宝":[{"教主夫人":["教主"]},
                              {"阿珂":"刺客"},
                              {"双儿":"天地会"},
                              {"爱心觉罗建宁":"公主"},
                              {"独臂神尼":{"韦小宝师父":{"兰陵王":"隐身"},"花木兰":[
                                      "唧唧复唧唧","木兰是战士",{"爸爸":["花和尚"]}]
                                        }},
                              {"陈圆圆":"丈母娘"},{"穆建平":"小郡主"}]},
                  1005:{"常鑫":["大黑哥","大烧饼","吃大煎饼","肉夹馍","自行车","井盖",]}
                  }
            ?
            ?
            # print(dic)
            # print(dic[1004]["韦小宝"][0]["教主夫人"][0])
            # print(dic[1005]["常鑫"][-1])
            # print(dic[1002]["汪峰"]["前妻2"][-1])
            # print(dic[1004]["韦小宝"][4]["独臂神尼"]["韦小宝师父"]["兰陵王"])
            # print(dic[1004]["韦小宝"][4]["独臂神尼"]["花木兰"][2]["爸爸"][0])
            ?
        5. set集合

          • 集合是没有值的字典,是无序的,可变的,天然去重

          • 集合的增删改查

            #增加
            add()#往集合中添加一个元素
            update(‘你好呀‘)#迭代增加
            #删除
            pop()#随机删除一个
            remove(‘哈哈‘)#指定元素删除
            clear()#清空
            #修改
            集合在修改的时候是先删除再修改
            #查找
            使用for循环进行查找
            set(‘HAHAH‘)#迭代添加
            ?
          • 集合其他操作

            & #交集
            | #并集
            - #差集
            ^ #对称差集
            > #父集
            < #子集
            forzenset()#冻结集合
            ?
            ?
            注意:(列表去重)
            # lst = [1,2,1,2,4,2,45,3,2,45,2345,]
            # print(list(set(lst)))
            ?
        6. 数据类型总结

          • # 列表删除  -- 从后向前删除
            # 创建一个新的列表,删除旧的列表
            # 字典删除 -- 循环的时候不能改变源数据的大小 (可以改变值)
            # 创建一个新的字典,删除旧的字典
            # 集合删除 -- 循环的时候不能改变源数据的大小
            ?
          • # python数据类型:
            # 可变:
            # list ,dict ,set
            # 不可变:
            # int bool str tuple
            # 有序:
            # list,tuple,str,int,bool
            # 无序:
            # dict,set
            # 取值方式:
            # 索引: str list tuple
            # 直接: set ,int ,bool
            # 键: dict
            ?

         

        小数据池和深浅拷贝

        1. 小数据池

          代码块:一个文件,一个函数,一个类,一个模块,终端中每一个行是一个代码块
          支持:
          ?
          数字:
           在同一代码块下 只要内容相同就采用相同的内存地址(-5以后就不是)
           数字在做乘法的时候范围 -5 ~ 256  ****
           数字在做乘法的时候不能使用浮点数
          字符串:
           在同一代码块下 只要内容相同就采用相同的内存地址
           乘法的时候总长度不能超过20   ****
           乘法的时候中文,特殊符号乘以1或0
          布尔值:
           在同一代码块下 只要内容相同就采用相同的内存地址
          ?
          小数据池:
          数字:  -5 ~ 256   ****
          字符串:
               在同一代码块下 只要内容相同就采用相同的内存地址
               乘法的时候总长度不能超过20   ****
               乘法的时候中文,特殊符号乘以0
          布尔值:
               在同一代码块下 只要内容相同就采用相同的内存地址
          小数据池的验证方法,必须脱离代码块才能进行验证
          先执行代码块的规则,在执行小数据的规则 --(驻留机制)
          ?

           

        2. 深浅拷贝

          #赋值:
          #   多个变量名指向同一个内存地址
          #   一个变量对其进行操作,其他变量查看时都变动
          #浅拷贝:
          #   lst[1:10] -- 是浅拷贝
          #   浅拷贝只拷贝第一层元素
          #   修改第一层元素是,新开辟的不进行改变
          #深拷贝:
          #   不可变的数据类型共用,可变的数据类型重新开辟一个空间
          #   对源数据进行修改,深拷贝的内容不进行改变
          ?
        3. 总结

          #代码块: 一个文件,一个函数,一个类,一个模块,终端中每一行
          #   数字: -5 ~ 256
          #   字符串: 乘法时总长度不能超过20
          #   布尔值: 内容相同内存地址相同
          #小数据池:
          #   数字: -5 ~ 256
          #   字符串: 乘法时总长度不能超过20
          #   布尔值: 内容相同内存地址相同
          #先执行代码块后执行小数据池
          #== is
          #   == 判断等号两边值是否相等
          #   is 判断两边的值内存地址是否相等
          ?
          ?
          # 浅拷贝的时候只拷贝第一层元素
          # 浅拷贝在修改第一层元素(不可变数据类型)的时候,拷贝出来的新列表不进行改变
          # 浅拷贝在替换第一层元素(可变数据类型)的时候,拷贝出来的新列表不进行改变
          # 浅拷贝在修改第一层元素中的元素(第二层)的时候,拷贝出来的新列表进行改变
          ?
          # 深拷贝开辟一个容器空间(列表),不可变数据公用,可变数据数据类型(再次开辟一个新的空间)
          # ,空间里的值是不可变的数据进行共用的,可变的数据类型再次开辟空间
          ?

        文件操作

        1. 文件操作

          #文件操作
          # open---打开文件
          # file---文件路径
          # mode---文件操作模式
          # encoding---文件编码集
          ?
        2. 文件操作模式

          #r,w,a:
          # r:读模式
          # read()读取全部内容
          # read(3)r,w,a模式下为为字符
          # readline()读取一行
          # readlines()一行一行读取,保存在一个列表中
          # w:写模式,先清空,后写
          # write()只能写入字符串
          # a:追加写模式:
          # 不管光标怎么移动都是在文件末尾进行追加写
          ------------------------------------------------
          #rb,wb,ab(字节模式,不用选择编码格式)
          # rb:读取字节模式
          # read(3)rb,wb,ab模式下读取的字节,
          # wb:清空写(字节)
          # write()先清空,后写入
          #-----------------------------------------------
          #r+,w+,a+
          # r+(读写)一定要先读后写
          # w+(写读)先清空,再写,后读
          # a+(追加,读)在文件末尾追加,读的时候为空要移动光标
          ?
        3. 其他操作

          #tell()查看光标的位置,返回的是字节的位置
          #seek():
          # seek(0,0)移动到文件的开头位置
          # seek(0,1)光标的当前位置
          # seek(0,2)移动到文件的末尾
          # seek(3)#按照字节进行移动,字节计算按照编码进行计算
          -------------------------------------------
          with open(文件操作名,模式,编码)as f:
             操作
          with open的好处:
                 1.可以同时打开多个文件
                 2.能够自动关闭文件
          -------------------------------------------
           修改文件内容:
                 1.创建一个新的文件
                 2.将文件中的内容进行替换
                 3.替换后的内容写入新文件中
                 4.改变文件名
          ?
             路径:
                 绝对路径: 从磁盘根部进行查找
                 相对路径: ../返回上一级  --推荐使用
                 转义:
                     1."C:\user\ner"
                     2. r"C:user er"  -- 推荐使用
          ?

        函数

        函数初识

        • 函数的基本结构

          def 关键字--定义函数
          func 函数名和变量的命名规则一样
          () 格式,用来船体参数,
          :申明函数定义语句的结束
          def func():
             print(‘哈啊哈‘)#函数体
          func()#调用函数
          ?
        • 函数的返回值

          return 返回值
          return的内容返回给了函数的调用
          return下方的代码不执行,终止这个函数
          return 返回多个内容的时候还是元组形式
          return 没有写返回值的时候返回的是None,不写return返回None
          def yue():
             print("打开手机")
             print("打开微信")
             return 111
             print("找到女友")
             print("晚上约吗")
             return "萝莉小姐姐","大妈","人妖"  # return 返回
             print("确实有点累")
          print(yue())  # 111
          print(1234)
          =========================================
          lst = [1,2,3,4,5]
          def func():
             for i in lst:
                 print(i)
             lst.append(input(">>>"))
             return lst
          ?
        • 函数的参数

          1:位置参数
          def yue(a,b,c):  # 形参
             print("打开手机")
             print(f"打开{a},{c},{b}")
             print("附近的人")
             print("找个妹子")
             print("聊一聊")
          yue(True,(12,4,3),[1,2,3,4]) # 实参
          2:默认参数
          def userinfo(name,age,sex="男"):  # 位置参数 > 默认参数
             print(name,sex,age)
          count = 5
          while count:
             name = input("name:")
             sex = input("sex(男性直接回车!):")
             age = input("age:")
             if sex == "女":
                 userinfo(name,age,sex)
             else:
                 userinfo(name, age)
             count -= 1
          3:关键字参数:
          def func(a,c,b=1): # a,c位置参数 ,b=1 是默认参数
             print(a,b,c)
          ?
          func(a=1,b=5,c=2) # a=1,b=5,c=2 是关键字参数
          4:混合参数
          def func(a,b,c):
             print(a,b,c)
          func(1,2,c=5) # 混合参数
          **************************************************************
          # 形参: 函数的定义中括号里是形参
          # 实参: 函数的调用括号里是实参
          # 位置传参时 形参和实参必须一一对应
          # 传参: 将实参传递给形参的过程就是传参
          ?
          # 函数的参数:
             # 形参: 函数定义的时候叫做形参
                 # 位置参数
                 # 默认参数
                 # 混合参数
          ?
             # 实参: 函数调用的时候叫做实参
                 # 位置参数
                 # 关键字参数
                 # 混合参数
          ?
             # 传参: 将实参传递给形参的过程叫做传参
          ?

        函数的动态参数

        #*args动态位置参数
        def func(a,b,*args):#*args是万能的位置参数,*在函数定义的时候叫聚合
           print(a,b,args)#接收的是元祖形式
        def func(a,b,*args):
           print(a,b*args)#*args在函数内部是打散的意思
        位置参数>动态位置参数>默认参数
        -------------------------------------------------
        #**kwargs动态关键字参数
        def func(a,b,**kwargs):#**kwargs接受的是关键字,字典的格式
           print(a,b,kwargs)#字典的格式
        def func(a,b,kwargs):
           print(a,b,*kwargs)#*kwargs获取到的是字典的键
        位置参数>动态位置参数>默认参数(关键字参数)>动态关键字参数
        -------------------------------------------------
        *args,**kwargs万能参数
        def func(*args,**kwargs):
           print(args,kwargs)
        ?

        函数的注释

        def func1(user,password):
           """
          密码加密
          :param user: 用户名 str
          :param password: 密码 str
          :return: 加密的密码 MD5
          """
           print(user,password)
        print(func.__doc__)#可以查看函数的注释
        ?

        名称空间

        • 命名空间

          在python解释器开始执行之后, 就会在内存中开辟一个空间, 每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了, 至于函数内部的变量和逻辑, 解释器是不关心的. 也就是说一开始的时候函数只是加载进来, 仅此而已, 只有当函数被调用和访问的时候, 解释器才会根据函数内部声明的变量来进行开辟变量的内部空间. 随着函数执行完毕, 这些函数内部变量占用的空间也会随着函数执行完毕而被清空.
          ?

           

        • 命名空间分类

          命名空间分类:
          1. 全局命名空间--> 我们直接在py文件中, 函数外声明的变量都属于全局命名空间
          2. 局部命名空间--> 在函数中声明的变量会放在局部命名空间
          3. 内置命名空间--> 存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置命名空间 
          ?
        • 加载的顺序

          #内置空间>全局空间>局部空间
          ?
        • 取值的顺序

          #局部空间>全局空间>内置空间
          ?
        • 作用域

          #全局作用域:
          内置空间+全局空间
          #局部作用域
          局部空间
          ?

         

        函数的嵌套

        # 函数中套函数
        # def func():
        #     a = 1
        #     def foo():
        #         b = 2
        #         print(b) # 2
        #         print(a) # 1
        #         def f1():
        #             print(b) # 2
        #         return f1()
        #     return foo()
        # print(func())
        ------------------------------------
        # 函数嵌套调用
        # def func():
        #     a = 1
        #     foo()
        #     print(a)
        #
        # def foo():
        #     b = 2
        #     print(b)
        # func()
        -------------------------------------
        # 函数嵌套参数的传递
        # def func(a):
        #     foo(a) #10
        #
        # def foo(e):
        #     b(e) # return 10
        #
        # def b(c):
        #     print(c)
        #     return 10
        #
        # print(func(5))
        -------------------------------------
        # 函数嵌套返回值的传递
        # def func(a):
        #     foo(a) #10
        # return 10
        # def foo(e):
        #     b(e)  
        # return 10
        # def b(c):
        #     print(c)
        #     return 10
        #
        # print(func(5))
        ?

        global和nonlacal

        #global修改变量的值
        # def func():
        #     global a # 声明修改全局变量的值
        #     a += 1
        #     print(a)
        # func()
        # print(a)
        ---------------------------------------------
        #nonlocal在外层的函数中,修改局部空间的变量值.完全不涉及全局变量,
        #只修改离它最近的一层,最近的一层没有变量继续向上找,直到找到最外层函数
        ?

        函数名的使用

        • 函数名可以当作值赋值给一个对象

          def func():
             print(‘哈哈‘)
          s=func
          s()
          ?
        • 函数名可以当作元素存放在容器中

          def func():
             print(‘哈哈‘)
          lst=[func,func,func]
          for i in lst:
             i()
          ?
        • 函数名可以当作另一个函数的参数

          def func(f):
             f()
          def foo():
             print(‘呵呵‘)
          func(foo)
          ?
        • 函数名可以当作函数的返回值

          def func():
             print(‘啊哈哈‘)
             def foo():
                 print(‘呵呵‘)
             return foo
          func()
          ?

        python3.6 f-string

        #可以填充字符串
        s=f"{‘haha‘}"
        #可以填充变量
        s1=f‘{s}‘
        #可以填充计算公式
        s2=f"{35+35}"
        #可以填充表达式
        s3=f"{a if 2>3 else b}"#三元表达式
        #可以填充大括号
        s4=f"{{{{1}}}}"#逢二取一
        ?

        迭代器

        • #list,dict,tuple,str,set都是可迭代对象,优点是可以灵活使用,可以直接查值,缺点是:消耗内存,不能迭代取值
          #__iter__()可以查看是不是一个可迭代对象
          #dir(list)#可以查看数据类型的所有的方法
          #同时拥有__iter__()和__next__()方法的就是一个迭代器
          #迭代器的优点是:节省内存,惰性机制(调用一次,取一次值)
          #缺点是:不灵活,不能查看全部的值,比较繁琐
          #迭代器的特性是:
          # 一次性使用,不能逆行取值,惰性机制节约内存
          #当容器中的数据量较大时,可以使用迭代器
          ?
        • #具有__iter__()方法的都是可迭代的对象
          # lst=[1,2,3,4,5,6,7,8,9]
          # new_lst=lst.__iter__()#可以将迭代对象转换成迭代器
          #__next__()方法可以取值,每次取一个,无法回退,
          # print(new_lst.__next__())
          # print(new_lst.__next__())
          ?

           

        for 循环的本质

        lst=[1,2,3,4,56,7,89]
        new_lst=lst.__iter__()
        while True:
           try:
               print(new_lst.__next__())
           except ExceptIteration:
          break
        ?

        递归函数

        #递归函数的特性
        #1:函数自己调用自己(不断调用自己本身)
        #2:有明确的结束条件
        #递:函数一直执行到条件结束
        #归:从结束条件返回
        -------------------------------
        def func(age):
           if age==4:
               return 18
           else:
               return func(age+1)-2
        print(func(1))
        #import sys
        sys.setrecursionlimit(400)设置函数的最大递归次数

        生成器

        • 什么是生成器

          #迭代器是python自带的一种节省空间的工具
          #生成器的本质就是一个迭代器
          #迭代器和生成器的区别是,一个是python自带的,一个是我们自己写的
          ?
        • 生成器的定义

          def func():
             print(1)
             yield ‘哈哈‘
             print(2)
             yield ‘呵呵‘
          g=func()#产生一个生成器
          print(next(g))#一个__next__()对应一个yield
          for i in g:#生成器可以使用for循环遍历
             print(i)
          ---------------------------------------
          print(func().__next__())#这种会不段产生新的生成器,这是 坑 坑 坑
          ?
        • 生成器的使用场景

          def func():
             lst=[]
             for i in range(1000000):
                 yield i
          g=func()
          foe i in range(50):
             print(next(g))
          #当数据量过大时,可以使用生成器来节省空间
          ?
        • 生成器的总结

          #在函数中将return改成yield就是一个生成器
          #yield会记录执行的位置,yield和return都是返回的意思
          #return可以写多个,都是只能执行一个,yield可以写多个,还可以返回多次
          #一个__next__()方法和一个yield一一对应,反则会报错
          #生成器可以使用for循环进行遍历,获取值
          #yield from可以将可迭代对象的元素逐个返回
          #在函数的内部,可以使用yield将while和for循环暂时暂停
          ?

        推导式总结

        • 列表推导式

          #循环模式
          print([i for i in [1,2,3,4,5,6,7]])
          #筛选模式
          print([i+1 for i in [1,2,3,4,56,7,8,9] if i % 2==0])
          #[变量(加工后的变量) for循环 加工方式]
          ?
        • 字典推导式

          #循环模式
          print({i:i+1 for i in range(20)})
          #筛选模式
          print(i:i+1 for i in range(20) if i % 2==0)
          #{键:值 for循环 加工条件}
          ?
        • 集合推导式

          #循环模式
          print({i for i in [1,2,3,4,6,7,9]})
          #筛选模式
          print({i+1 for i in range(20)  if i %2==0})
          #{变量(加工后的变量) for循环 加工条件}
          ?
        • 生成器表达式

          #循环模式
          g=(i for i in range(20))
          print(next(g))
          #筛选模式
          g=(i for i in range(20) if i %2==0)
          print(next(g))
          print(list((i for i in range(20))))#list()方法内部有循环取值
          #(变量(加工后的变量 for循环 加工条件))
          ?

        内置函数一

         

        内置函数函数的意思
        all() all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。
        any() any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True
        bytes() bytes 函数返回一个新的 bytes 对象,该对象是一个 0 <= x < 256 区间内的整数不可变序列。它是 bytearray 的不可变版本
        callable() callable() 函数用于检查一个对象是否是可调用的。如果返回 True,object 仍然可能调用失败;但如果返回 False,调用对象 object 绝对不会成功。
        chr() chr() 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符,返回值是当前整数对应的 ASCII 字符。
        complex() complex() 函数用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。
        divmod() python divmod() 函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。
        eval() eval() 函数用来执行一个字符串表达式,并返回表达式的值。
        exec() exec 执行储存在字符串或文件中的Python语句,相比于 eval,exec可以执行更复杂的 Python 代码。
        frozenset() frozenset() 返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。
        globals() globals() 函数会以字典类型返回当前位置的全部全局变量。
        hash() hash() 用于获取取一个对象(字符串或者数值等)的哈希值。
        help() help() 函数用于查看函数或模块用途的详细说明
        id() id() 函数用于获取对象的内存地址。
        input() 输入,获取到的是字符串类型
        int() 整数类型
        iter() iter() 函数用来生成迭代器。
        locals() locals() 函数会以字典类型返回当前位置的全部局部变量。对于函数, 方法, lambda 函式, 类, 以及实现了 call 方法的类实例, 它都返回 True。
        next() next() 返回迭代器的下一个项目。
        oct() oct() 函数将一个整数转换成8进制字符串。
        ord() ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。
        pow() pow() 方法返回 xy(x的y次方) 的值
        repr() repr() 函数将对象转化为供解释器读取的形式。
        round() ound() 方法返回浮点数x的四舍五入值。

         

        内置函数二

        函数名函数的意思
        dir() 查看函数的所有方法
        abs() 绝对值,返回的是正数
        enumerate() 枚举,(‘‘可迭代对象‘‘,‘序号的起始值‘),默认起始值为0
        zip() 拉链,数据合并,按照最小的进行合并,返回的是个对象的内存地址 list(zip("可迭代对象","可迭代对象")) 返回的是[(1,2),(2,3)]
        min() 求最小值,key是比较的方法 min("可迭代对象",key=abs) #key指定查找最小值时的规则
        max() 求最大值,key是比较的方法 max("可迭代对象",key=abs) #key指定查找最大值时的规则
        sum() 求和 sum(list,tuple,set)
        range()和2.7xrange() 获取的是一个可迭代对象,2.7中range获取的是一个列表
        print() 打印,sep元素之间的连接符,end是末尾的换行符
        list() 转换成列表类型,自带循环
        dict() 转换成字典类型,数据格式为dict=((1,2),(2,3))
        format ‘<‘左对齐‘>‘右对齐^居中,,,,b,d,o,x进制转换,08八位显示
        bin() 十进制转换二进制
        filter(过滤函数,迭代对象) 过滤,获取的是一个内存地址 filter("函数名","可迭代对象") 写函数的时候可以指定过滤条件
        map() 映射对象, map("函数名","可迭代对象") 写函数的时候可以指定对元素的操作
        reversed 反转,获取的是一个可迭代对象 reversed("可迭代对象") # 对可迭代对象进行翻转(不改变源数据)
        sorted 对数据进行排序,key指的是排序的规则 sorted("可迭代对象",key="函数名",reverse=True) key是指定排序的规则(默认是升序)写了reverse=True就是降序
        reduce (from functools import reduce) 累计算,根据计算的函数的条件进行计算 reduce("函数","可迭代对象") # 函数指定累计算的方式 (from functools import reduce)

        lambda匿名函数

        lambda是一个定义函数的关键字,必须有返回值,没有也要写None,只能返回一个数据类型,形参可以不写
        # f = lambda x,y:(x,y)
        # print(f(1,2))
        # print(f.__name__)
        # print((lambda x:x)(2)) # 同一行定义 同一行调用
        # lst = [lambda i:i*i for i in range(10)](面试)
        # print(lst[2](2))
        # lst = [lambda :i*i for i in range(10)](面试)
        # print(lst[2]())
        ---------------------------------
        # lst = list((lambda i:i*i for i in range(5)))
        # print(lst[1](4))
        ?
        # lst = [x for x in (lambda :i**i for i in range(5))]
        # print(lst[2]())
        #解构
        # lst1 = []
        # def func():
        #     for i in range(5):
        #         def foo():
        #             return i**i
        #         yield foo
        #
        # for x in func():
        #     lst1.append(x)
        # print(lst1[2]())
        ?

        闭包

        在嵌套函数内,使用非全局变量(且不是本层变量) -- 就是闭包
        __closure__ 判断是否是闭包
        闭包的作用
        1.  保证数据的安全性
        2.  装饰器的本质
        # print(ret.__code__.co_freevars) # 获取的是自由变量
        # print(ret.__code__.co_varnames) # 获取的是局部变量
        ---------------------------------
        # def func():
        #     avg_lst = [] # 自由变量
        #     def foo(pirce):
        #         avg_lst.append(pirce)
        #         avg = sum(avg_lst) / len(avg_lst)
        #         return avg
        #     return foo
        # ret = func()
        ?

        装饰器

        • 装饰器的规则

          # 开放封闭原则:
          # 扩展是开放的(增加新功能)
          # 修改源码是封闭(修改已经实现的功能)
          # 在不改变源代码及调用方式的基础下额外增加新的功能
          # 装饰器:用来装饰的工具
          ?
        • # 版一:
          import time
          # start_time = time.time()
          # def func():
          #     time.sleep(2) #睡眠 (模拟网络延时)
          #     print("我要飞")
          # func()
          # print(time.time() - start_time)
          # start_time = time.time()
          # def foo():
          #     time.sleep(3) #睡眠 (模拟网络延时)
          #     print("我是小明,我飞的比你高")
          # foo()
          # print(time.time() - start_time)
          --------------------------------------------------
          # 版二:
          # def times(f):
          #     start_time = time.time()
          #     f()
          #     print(time.time() - start_time)
          # def foo():
          #     time.sleep(3) #睡眠 (模拟网络延时)
          #     print("我是小明,我飞的比你高")
          # def func():
          #     time.sleep(1) #睡眠 (模拟网络延时)
          #     print("我是业儿,我起不来")
          # s = func
          # func = times
          # s = foo
          # foo = times
          # foo(s)
          ----------------------------------------------------
          # 版三(初识版装饰器):
          # def times(f):
          #     def inner():
          #         start_time = time.time()
          #         f()
          #         print(time.time() - start_time)
          #     return inner
          # def foo():
          #     time.sleep(1) #睡眠 (模拟网络延时)
          #     print("我是李业,我快!")
          # foo = times(foo)
          # foo()
          --------------------------------------------------
          import time
          # def wrapper(f):
          #     def inner(*args,**kwargs):
          #         "被装饰前"
          #         start_time = time.time()
          #         f(*args,**kwargs) # func("alex")
          #         print(time.time() - start_time)
          #         "被装饰后"
          #     return inner # 切记不要加括号
          #
          #
          # def func(*args,**kwargs):
          #     print(f"这是{args}函数,李业还是不行")
          #     time.sleep(2) #模拟网络延时
          #
          #
          # func = wrapper(func)
          # func("alex","sur")
          ----------------------------------------------------
          # import time
          # def wrapper(f):
          #     def inner(*args,**kwargs):
          #         "被装饰前"
          #         start_time = time.time()
          #         f(*args,**kwargs) # func("alex")
          #         print(time.time() - start_time)
          #         "被装饰后"
          #     return inner # 切记不要加括号
          # # @wrapper # func = wrapper(func)
          # def func(*args,**kwargs):
          #     print(f"这是{args}函数,李业还是不行")
          #     time.sleep(2) #模拟网络延时
          # # @wrapper # foo = wrapper(foo)
          # def foo(*args,**kwargs):
          #     print(f"这是{args}函数,常鑫穿齐*小短裤")
          #     time.sleep(3) #模拟网络延时
          # func = wrapper(func)
          # foo = wrapper(foo)
          # func("alex","sur")
          # foo("alex","sur")
          ---------------------------------------------------
          ?
        • 语法糖
          # 语法糖 -- 甜
          # 语法糖必须放在被装饰的函数正上方
          import time
          # def wrapper(f):
          #     def inner(*args,**kwargs):
          #         "被装饰前"
          #         start_time = time.time()
          #         ret = f(*args,**kwargs) # func("alex")
          #         print(time.time() - start_time)
          #         "被装饰后"
          #         return ret
          #     return inner # 切记不要加括号
          #
          # @wrapper # func = wrapper(func)
          # def func(*args,**kwargs):
          #     print(f"这是{args}函数,李业还是不行")
          #     time.sleep(2) #模拟网络延时
          #     return "alex"
          # print(func())
          ?
        • 标准版装饰器
          # 标准版(装饰器):
          # def func(a): #a是要被装饰的函数名
          #     def foo(*args,**kwargs):
          #         "装饰之前的操作"
          #         ret = a(*args,**kwargs)
          #         "装饰之后的操作"
          #         return ret
          #     return foo
          # @func
          # def f1(*args,**kwargs):
          #     print(f"这是一个{args}")
          #     return "我可以返回了"
          # f1(1,2,3,34,4,5)
          ?

        带参数的装饰器

        在装饰器的基础上再套一层
        login_dic = {
           "username": None,
           "flag": False
        }
        # 正确的案例
        msg = """
        QQ
        微信
        抖音
        邮箱
        请输入您要选择登陆的app:
        """
        chose = input(msg).upper()
        ?
        def auth(argv):
           def wrapper(func):
               def inner(*args,**kwargs):
                   if login_dic["flag"]:
                       func(*args,**kwargs)
                   else:
                       if argv == "QQ":
                           print("欢迎登陆QQ")
                           user = input("username:")
                           pwd = input("password:")
                           if user == "alex" and pwd == "alex123":  # qq
                               login_dic["flag"] = True
                               login_dic["username"] = user
                               func(*args,**kwargs)
                           else:
                               print("用户名或密码错误!")
                       elif argv == "微信":
                           print("欢迎登陆微信")
                           user = input("username:")
                           pwd = input("password:")
                           if user == "1351101501" and pwd == "alex":  # 微信
                               login_dic["flag"] = True
                               login_dic["username"] = user
                               func(*args, **kwargs)
                           else:
                               print("用户名或密码错误!")
                       elif argv == "抖音":
                           print("来了,老弟!")
                           user = input("username:")
                           pwd = input("password:")
                           if user == "alexdsb" and pwd == "alex":  # 抖音
                               login_dic["flag"] = True
                               login_dic["username"] = user
                               func(*args, **kwargs)
                           else:
                               print("用户名或密码错误!")
                       else:
                           print("欢迎登陆dab邮箱")
                           user = input("username:")
                           pwd = input("password:")
                           if user == "alexdsb@dsb.com" and pwd == "alex":  # 邮箱
                               login_dic["flag"] = True
                               login_dic["username"] = user
                               func(*args, **kwargs)
                           else:
                               print("用户名或密码错误!")
               return inner
           return wrapper
        @auth("QQ")
        def foo():
           print("这是一个被装饰的函数")
        # wrapper = auth(chose)
        # foo = wrapper(foo)
        foo()
        """
        # @auth(chose) 相等于以下两行代码的解构
        # wrapper = auth(chose)
        # foo = wrapper(foo)
        """
        ?

        多个装饰装饰一个函数

        # 先执行离被装饰的函数最近的语法糖
        # 小技巧:进入装饰器从上往下,走到最会一个装饰器执行被装饰的函数,退出装饰器从下往上走
        # def wrapper1(func):
        #     def inner1(*args,**kwargs):
        #         print(1)
        #         func(*args,**kwargs)
        #         print(11)
        #     return inner1
        #
        # def wrapper2(func): # func == foo
        #     def inner2(*args,**kwargs):
        #         func(*args, **kwargs)
        #         print(22)
        #     return inner2
        #
        # def wrapper3(func):
        #     def inner3(*args,**kwargs):
        #         print(3)
        #         func(*args, **kwargs)
        #         print(33)
        #     return inner3
        ?
        # @wrapper1 # 1 11
        # @wrapper3 # 3 33
        # @wrapper2 # 8 22
        # def foo():
        #     print(8)
        #foo()
        ?

        模块

        自定义模块

        • 模块分类

          #1.内置模块(标准库) -- python解释器自带的.py文件(模块)
          #2.第三方模块(各种大神写的) -- 需要额外下载的 (pypi)
          #3.自定义模块(自己写的) -- 不需要额外下载
          ?
        • 模块的优点

          #1:避免写重复代码
          #2:可以多次利用
          #3:拿来主义
        • 模块导入及模块导入时发生的事情

          import #导入(拿工具箱)
          #模块导入时,发生的事情:
          #1:当前的名称空间中开辟一个新的空间(模块)
          #2:将模块中所有的代码执行
          #3:通过模块名,进行函数查找(工具)
          ------------------------------------
          import time
          print(time.time())
          ------------------------------------
          #错误实例
          import time.py
          print(time.py.time())
        • 使用别名可以使模块名变短

          import time as t
          print(t.time())
          -------------------------------------
          #使用别名也可以做一些模块的兼容性
          # 做一兼容性
          # choose = input(msg)
          # if choose == "1":
          #     import meet
          #     meet.func()
          # elif choose == "2":
          #     import test
          #     test.func()
          ?
          # # 做一兼容性
          # choose = input(msg)
          # if choose == "1":
          #     import meet as t
          # elif choose == "2":
          #     import test as t
          #
          # t.func()
          ?
        • from调用方法

          import和from的区别
          import是直接吧工具箱拿过来
          1:优点是不会和当前文件定义的变量或函数发生冲突
          2:缺点是占用内存比较大
                 # import test
                 # name = "宝元"
                 # print(test.name)
                 # print(name
          from 是导入模块中的一些函数或者变量,(直接拿工具)
          1:优点是内存占用小
          2:缺点是会和当前的文件定义的变量或者函数发生冲突
                 # from test import * 会出现覆盖的现象,不能解决
                 # name = "宝元"
                 # from test import name
                 # print(name)
          ?
                 # 解决方法:
                     # name = "宝元"
                     # from test import name as n
                     # print(name)
                     # print(n)
          ?
        • all方法

          # __all__ = ["可以被导入的函数名和变量名"]#在被导入的模块中使用
          ?
        • 模块的两种用法

          #1.脚本(在cmd中执行 python test.py)
          #2.模块(不使用或者导入)
          ?
        • main方法

          # from test import *
          # if __name__ == ‘__main__‘: # 测试接口
          #     func()
          # 在当前模块中使用__name__ 就是 "__main__"
          # 当模块被导入的时候__name__就是被导入的模块名
          ?
        • 导入路径

          # import meet
          # print(meet.name)
          --------------------------------------------
          # 使用相对路径:
          # from day15.t1 import meet
          # print(meet.name)
          ----------------------------------------
          # 使用绝对路径:
          # 错误示例:
             # from r"D:" import meet
             # from ../
          ==========================================
          # 正确的绝对路径:
          # from sys import path
          # path.insert(0,"D:\")
          # import meet
          # print(meet.name)
          ?

        time模块

        import time
        print(time.time())#获取时间戳 浮点数
        print(time.sleep(2))#睡眠,阻塞
        print(time.strftime(‘%Y-%m-%d %H:%M:%S‘))#时间显示格式,页面显示的格式
        print(time.gmtime())#结构化时间,元祖的形式(命名元祖),可以根据索引和元素进行查找
        time.struct_time(tm_year=2019, tm_mon=7, tm_mday=25, tm_hour=8, tm_min=10, tm_sec=50, tm_wday=3, tm_yday=206, tm_isdst=0)
        #time.localtime获取的是当地时间
        # print(time.gmtime()[0])
        # print(time.gmtime().tm_year)
        #将时间戳转换成字符串时间
        print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(1564028611.631374)))
        #将字符串时间转换成时间戳
        print(time.mktime(time.strptime("2024-3-16 12:30:30","%Y-%m-%d %H:%M:%S")))
        ---------------------------------------
        重点:
        # time重点:
        # time.time()
        # time.sleep()
        # time.gmtime() / time.localtime() #
        # time.strftime("格式化","结构化时间") #
        # time.strptime("字符串","格式化")
        # time.mktime()
        ****************************************************************
        ?

        datatime模块

        print(type(datetime.now()))获取当前时间,获取的是一个对象
        print(datetime(2019,5,21,15,14,00) - datetime(2019,5,20,14,20,00))计算时间差
        # 将当前时间转化成时间戳
        # t = datetime.now()
        # print(t.timestamp())
        -----------------------------------------
        # 将时间戳转化成当前时间
        # import time
        # print(datetime.fromtimestamp(15000000000))
        -----------------------------------------------------
        # 将字符串转成对象
        # print(type(datetime.strptime("2019-10-10 22:23:24","%Y-%m-%d %H:%M:%S")))
        -----------------------------------------------------
        # 将对象转成字符串
        # print(str(datetime.now()))
        # print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        ------------------------------------------------------
        # datetime加减
        # print(datetime.now() + timedelta(hours=30 * 24 * 12))
        # print(datetime.now() - timedelta(hours=30 * 24 * 12))
        ***********************************************************
        # datatime模块
        import datetime
        now_time = datetime.datetime.now()  # 现在的时间
        # 只能调整的字段:weeks days hours minutes seconds
        print(datetime.datetime.now() + datetime.timedelta(weeks=3)) # 三周后
        print(datetime.datetime.now() + datetime.timedelta(weeks=-3)) # 三周前
        print(datetime.datetime.now() + datetime.timedelta(days=-3)) # 三天前
        print(datetime.datetime.now() + datetime.timedelta(days=3)) # 三天后
        print(datetime.datetime.now() + datetime.timedelta(hours=5)) # 5小时后
        print(datetime.datetime.now() + datetime.timedelta(hours=-5)) # 5小时前
        print(datetime.datetime.now() + datetime.timedelta(minutes=-15)) # 15分钟前
        print(datetime.datetime.now() + datetime.timedelta(minutes=15)) # 15分钟后
        print(datetime.datetime.now() + datetime.timedelta(seconds=-70)) # 70秒前
        print(datetime.datetime.now() + datetime.timedelta(seconds=70)) # 70秒后
        ?
        current_time = datetime.datetime.now()
        # 可直接调整到指定的 年 月 日 时 分 秒 等
        ?
        print(current_time.replace(year=1977))  # 直接调整到1977年
        print(current_time.replace(month=1))  # 直接调整到1月份
        print(current_time.replace(year=1989,month=4,day=25))  # 1989-04-25 18:49:05.898601
        ?
        # 将时间戳转化成时间
        print(datetime.fromtimestamp(1232132131))  # 2009-01-17
        ?

        random模块

        print(random.random())#在0~1之间随机生成一个浮点数
        print(random.uniform(0,10))#在0~10时间随机生成一个浮点数,可以指定范围
        print(random.randint(1,10))#随机生成一个整数,可以指定范围
        print(random.randrange(1,5,2))#起始终止步长,生成一个数字
        print(random.chioce([1,2,3,4,5,6]))#随机选择一个元素
        print(random.chioces([1,2,3,4,5,6,7]),k=2)#随机选择两个元素,会有重复的
        print(random.sample((1,2,3,4,5,6,7,8)),k=2)#随机选择两个元素,不会有重复的,除非只有两个
        print(random.shuffle(lst))#打乱顺序
        *************************************************
        >>> import random
        #随机小数
        >>> random.random()     # 大于0且小于1之间的小数
        0.7664338663654585
        >>> random.uniform(1,3) #大于1小于3的小数
        1.6270147180533838
        ?
        #随机整数
        >>> random.randint(1,5)  # 大于等于1且小于等于5之间的整数***
        >>> random.randrange(1,10,2) # 大于等于1且小于10之间的奇数***
        ?
        #随机选择一个返回
        >>> random.choice([1,‘23‘,[4,5]])  # #1或者23或者[4,5]
        #随机选择多个返回,返回的个数为函数的第二个参数***
        >>> random.choices([1,2,3,4],k=2) # 选择两个元素,会有重复,可控制元素个数***
        >>> random.sample([1,‘23‘,[4,5]],k=2) # #列表元素任意2个组合,不会重复(原列表有重复就会出现重复),可控制元素个数***
        [[4, 5], ‘23‘]
        ?
        #打乱列表顺序
        >>> item=[1,3,5,7,9]
        >>> random.shuffle(item) # 对原列表打乱次序
        >>> item
        [5, 1, 3, 7, 9]
        >>> random.shuffle(item)
        >>> item
        [5, 9, 7, 1, 3]
        ?

        序列化模块

        • json

          #     1.dumps loads
                     # lit = [1,22,3,3,45]
                     # print(json.dumps(lit),type(json.dumps(lit)))
                     # str_lst = json.dumps(lit)
                     # lst = json.loads(str_lst)
                     # print(lst,type(lst))
          ?
                     # dumps 将对象转换(序列化)成字符串
                     # loads 将字符串转换(反序列化)成对象
          ?
                     # dic = {‘username‘:‘宝元‘}
                     # str_dic = json.dumps(dic) # 序列化
                     # str_dic = json.dumps(dic,ensure_ascii=False) # ensure_ascii=False 关闭ascii码
                     # print(str_dic,type(str_dic))
                     # dic1 = json.loads(str_dic) # 反序列化
                     # print(dic1,dic1["username"])
          ?
          #     2.dump load
                     # import json
                     # lit = [1,22,3,3,45]
                     # 同时写多个内容 进行序列化
                     # lst = [1,2,3,4,56,]
                     # f = open("info","w",encoding="utf-8")
                     # f.write(json.dumps(lst) + " ")
                     # f.write(json.dumps(lst) + " ")
                     # f.write(json.dumps(lst) + " ")
                     # f.write(json.dumps(lst) + " ")
                     # f.write(json.dumps(lst) + " ")
                     # f.close()
          ?
                     # dump: 将对象转换(序列化)成字符串,写入文件
                     # load: 将文件中字符串转换(反序列)成对象
          ?
                     # 同时读多个内容进行反序列
                     # f1 = open("info","r",encoding="utf-8")
                     # for i in f1:
                     #     l = json.loads(i)
                     #     print(l)
                     # f1.close()
          ?
          ?
        • pickle模块

          # pickle 序列化 - nb(python所有对象进行转换)
          # python自带的(只有python可以用)
          # 两组4个方法:
          #1. dumps loads
                 # import pickle
          ?
                 # lst = [12,3,4,5,768]
                 # t_list = pickle.dumps(lst) # 转换成类似字节
                 # print(t_list)
                 # print(pickle.loads(t_list)[-1])
          ?
                 # dic = {"user":"郭宝元"}
                 # t_list = pickle.dumps(dic) # 转换成类似字节
                 # print(t_list)
                 # print(pickle.loads(t_list))
          ?
                 # def func():
                 #     print(111)
          ?
                 # import json
                 # fun = json.dumps(func)
                 # print(fun)
          ?
                 # fun = pickle.dumps(func)
                 # print(fun)
                 # pickle.loads(fun)()
          ?
          #2. dump load
          # import pickle
          # dic = {"usern":"baoyuian"}
          # dic = {"usern":"宝元"}
          # pickle.dump(dic,open("info","wb"))
          # print(pickle.load(open("info","rb")))
          ?
          # import pickle
          # dic = {"user":"123"}
          # pickle.dump(dic,open("info","ab"))
          ?
          # import pickle
          # dic = {"1":2}
          # f = open("info","wb")
          # s = " ".encode("utf-8")
          # f.write(pickle.dumps(dic)+ s)
          # f.write(pickle.dumps(dic)+ s)
          # f.write(pickle.dumps(dic)+ s)
          # f.close()
          #
          # f1 = open("info","rb")
          # for i in f1:
          #     print(pickle.loads(i))
          ?
          # 推荐使用json
          #   json是各种语言通用的
          ?
          ?

        os模块

        • os模块是程序员通过python向操作系统发送指令的交互接口

          import os
          #工作目录
          # print(os.getcwd())#获取当前的工作路径
          # print(os.chdir())#修改工作路径
          # print(os.curdir)
          # print(os.pardir)
          #文件夹
          # print(os.mkdir(‘aaa‘))
          # print(os.rmdir(‘aaa‘))
          # print(os.makedirs(‘aaa/bbb/ccc‘))
          # print(os.removedirs(‘aaa/bbb/ccc‘))
          # print(os.listdir(‘E:python24期笔记day17‘))
          #文件相关
          # print(os.rename(‘aa.txt‘,‘bb.txt‘))#修改文件名
          # print(os.remove(‘sss‘))#删除文件
          #路径相关
          # print(os.path.abspath(‘F:oldboyday17os模块.py‘))#获取绝对路径
          # print(os.path.dirname(‘F:oldboyday17os模块.py‘))#获取文件夹路径
          # print(os.path.basename(‘F:oldboyday17os模块.py‘))#获取文件目录
          # print(os.path.split(‘F:oldboyday17os模块.py‘))#对文件夹和文件分割
          # print(os.path.isabs(‘F:oldboyday17os模块.py‘))#判断是不是绝对路径
          # print(os.path.isdir(‘F:oldboyday17‘))#判断是不是一个目录
          # print(os.path.isfile(‘F:oldboyday17os模块.py‘))#判断是不是一个文件名
          # print(os.path.exists(‘F:oldboyday17os模块.py‘))#判断路径存不存在
          # print(os.path.join())拼接路径
          # os.path.getatime()查看文件的最后访问时间
          # os.path.getmtime()#查看文件的最后修改时间
          # os.path.getctime()#文件的创建时间
          # os.path.getsize()#路径的字节大小,按照kb返回
          ?

        hashlib模块

        # md5,sha1,sha256,sha512
        # 1.只要明文相同密文就是相同的
        # 2.只要明文不相同密文就是不相同的
        # 3.不能反逆(不能解密) -- md5中国人破解了
        # 加密:
        #     1.加密的内容
        #     2.将要加密的内容转成字节
        ?
        # 最常用是的md5,平时加密的时候使用sha1
        ?
        # 加盐
        ?
        # 加固定盐
        # import hashlib
        # md5 = hashlib.md5("常鑫".encode("utf-8"))
        # md5.update("alex123".encode("utf-8"))
        # print(md5.hexdigest())
        #
        # md5 = hashlib.md5()
        # md5.update("alex123".encode("utf-8"))
        # print(md5.hexdigest())
        ?
        ?
        # 动态加盐
        ?
        # user = input("username:")
        # pwd = input("password")
        #
        # import hashlib
        # md5 = hashlib.md5(user.encode("utf-8"))
        # md5.update(pwd.encode("utf-8"))
        # print(md5.hexdigest())
        ?
        # md5 = hashlib.md5()
        # md5.update(pwd.encode("utf-8"))
        # print(md5.hexdigest())
        ?
        # 767db14ed07b245e24e10785f9d28e29
        ?
        # f = open(r"F:s24day17python-3.6.6-amd64.exe","rb")
        # import hashlib
        # md5 = hashlib.md5()
        # md5.update(f.read())
        # print(md5.hexdigest())
        ?
        # ss = "baoyuanalextaibai"
        # s = "baoyuan"
        # s1 = "alex"
        # s2 = "taibai"
        # import hashlib
        # md5 = hashlib.md5()
        # md5.update(ss.encode("utf-8"))
        # print(md5.hexdigest())
        #
        #
        # md5 = hashlib.md5()
        # md5.update(s.encode("utf-8"))
        # md5.update(s1.encode("utf-8"))
        # md5.update(s2.encode("utf-8"))
        # print(md5.hexdigest())
        ?
        # 节省内存
        ?
        # f = open(r"F:s24day17python-3.6.6-amd64.exe","rb")
        # import hashlib
        # md5 = hashlib.md5()
        # while True:
        #     msg = f.read(1024)
        #     if msg:
        #         md5.update(msg)
        #     else:
        #         print(md5.hexdigest())
        #         break
        ?

        collections模块

        collections模块
        在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
        ?
        1.namedtuple: 生成可以使用名字来访问元素内容的tuple
        ?
        2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
        ?
        3.Counter: 计数器,主要用来计数
        ?
        4.OrderedDict: 有序字典
        ?
        5.defaultdict: 带有默认值的字典
        ====================================================================================
        namedtuple
        我们知道tuple可以表示不变数据,例如,一个点的二维坐标就可以表示成:
        ?
        p = (1, 2)
        但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。
        ?
        这时,namedtuple就派上了用场:
        ?
        from collections import namedtuple
        Point = namedtuple(‘Point‘, [‘x‘, ‘y‘])
        p = Point(1, 2)
        print(p)
        结果:Point(x=1, y=2)
        ?
        类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:
        ?
        namedtuple(‘名称‘, [属性list]):
        Circle = namedtuple(‘Circle‘, [‘x‘, ‘y‘, ‘r‘])
        deque
        使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
        ----------------------------------------------------------------------------------
        deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
        ?
        from collections import deque
        q = deque([‘a‘, ‘b‘, ‘c‘])
        q.append(‘x‘)
        q.appendleft(‘y‘)
        q
        deque([‘y‘, ‘a‘, ‘b‘, ‘c‘, ‘x‘])
        deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
        ------------------------------------------------------------------------
        OrderedDict
        使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
        ?
        如果要保持Key的顺序,可以用OrderedDict:
        ?
        from collections import OrderedDict
        d = dict([(‘a‘, 1), (‘b‘, 2), (‘c‘, 3)]) # 另一种定义字典的方式
        print(d)
        # 结果:
        {‘a‘: 1, ‘c‘: 3, ‘b‘: 2}
        ?
        od = OrderedDict([(‘a‘, 1), (‘b‘, 2), (‘c‘, 3)])
        print(od)
        # 结果:
        OrderedDict([(‘a‘, 1), (‘b‘, 2), (‘c‘, 3)])
        注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:
        ?
        >>> od = OrderedDict()
        >>> od[‘z‘] = 1
        >>> od[‘y‘] = 2
        >>> od[‘x‘] = 3
        >>> od.keys() # 按照插入的Key的顺序返回
        [‘z‘, ‘y‘, ‘x‘]
        --------------------------------------------------------------------------
        defaultdict
        有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
        ?
        即: {‘k1‘: 大于66 , ‘k2‘: 小于66}
        ?
        li = [11,22,33,44,55,77,88,99,90]
        result = {}
        for row in li:
           if row > 66:
               if ‘key1‘ not in result:
                   result[‘key1‘] = []
               result[‘key1‘].append(row)
           else:
               if ‘key2‘ not in result:
                   result[‘key2‘] = []
               result[‘key2‘].append(row)
        print(result)
        ?
        from collections import defaultdict
        values = [11, 22, 33,44,55,66,77,88,99,90]
        my_dict = defaultdict(list)
        ?
        for value in  values:
           if value>66:
               my_dict[‘k1‘].append(value)
           else:
               my_dict[‘k2‘].append(value)
        使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
        ?
        from collections import defaultdict
        dd = defaultdict(lambda: ‘N/A‘)
        dd[‘key1‘] = ‘abc‘
        # key1存在
        print(dd[‘key1‘])
        dd[‘key2‘] # key2不存在,返回默认值
        print(dd[‘key2‘])
        -------------------------------------------------
        Counter
        Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。
        ?
        c = Counter(‘abcdeabcdabcaba‘)
        print c
        输出:Counter({‘a‘: 5, ‘b‘: 4, ‘c‘: 3, ‘d‘: 2, ‘e‘: 1})
        ?

        re模块

        s=‘lijie_李杰_l	lilililijiee123@‘
        #w匹配字母数字,下划线包括中文
        print(re.findall(‘w‘,s))
        #W匹配非字母数字,下划线包括中文
        print(re.findall(‘W‘,s))
        #s匹配任意空格,换行符,制表符
        print(re.findall(‘s‘,s))
        #S匹配非任意空格,换行符,制表符
        print(re.findall(‘S‘,s))
        #d匹配数字
        print(re.findall(‘d‘,s))
        #D匹配非数字
        print(re.findall(‘D‘,s))
        #A或^匹配开头的内容
        print(re.findall(‘Alijie‘,s))
        print(re.findall(‘^lijie‘,s))
        #或$匹配结尾的内容
        print(re.findall(‘123@‘,s))
        print(re.findall(‘123@$‘,s))
        # 匹配换行符和制表符
        print(re.findall(‘ ‘,s))
        print(re.findall(‘ ‘,s))
        #.匹配任意一个内容(换行符除外)
        print(re.findall(‘l.j‘,s))
        print(re.findall(‘l.j‘,s,re.DOTALL))#.匹配任意时,可以匹配所有
        #[]指定匹配的范围
        print(re.findall(‘[A-Za-z0-9]‘,s))
        #[^]匹配指定范围之外的
        print(re.findall(‘[^a-z]‘,s))
        #*匹配0个或多个内容
        print(re.findall(‘li*‘,s))#贪婪匹配
        #+匹配1个或多个内容
        print(re.findall(‘li‘,s))#贪婪匹配
        #?匹配0个或一个内容
        print(re.findall(‘li?‘,s))
        #{}重复匹配指定字符几次
        print(re.findall(‘l{1}‘,s))
        #{1,6}指定重复匹配指定字符的次数范围
        print(re.findall(‘l{1,6}‘,s))
        #|或者
        print(re.findall(‘li|jie‘,s))
        #()匹配括号里的内容
        print(re.findall(‘l(.+?)j‘,s))
        print(re.findall(‘l(?:.+?)l‘,s))#()匹配时?:可以将括号外面的一起返回
        #search匹配一个,匹配到返回的是一个对象,查看元素用group()方法
        print(re.search(‘li‘,s))
        #match从字符串的开头查找,返回一个对象,查看元素用group()方法
        print(re.match(‘li‘,s))
        #finditer返回一个迭代器
        a=re.finditer(‘w‘,‘你好世界‘)
        print(next(a).group())#用group查看值
        #split分割
        print(re.split(‘l‘,s))
        #sub替换
        print(re.sub(‘li‘,‘哈哈‘,‘lijieljie‘))
        #?P分组起名
        print(re.findall(‘(?P<aaa>w)jie‘,s).group(‘aaa‘))
        #.转义
        # 匹配所有的数字(包含小数包含负号)
        # print(re.findall("-?d+.d+|-?d+",s))
        ?
        元字符匹配内容
        w 匹配字母(包含中文)或数字或下划线
        W 匹配非字母(包含中文)或数字或下划线
        s 匹配任意的空白符
        S 匹配任意非空白符
        d 匹配数字
        D p匹配非数字
        A 从字符串开头匹配
        z 匹配字符串的结束,如果是换行,只匹配到换行前的结果
        匹配一个换行符
        匹配一个制表符
        ^ 匹配字符串的开始
        $ 匹配字符串的结尾
        . 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
        [...] 匹配字符组中的字符
        [^...] 匹配除了字符组中的字符的所有字符
        * 匹配0个或者多个左边的字符。
        + 匹配一个或者多个左边的字符。
        匹配0个或者1个左边的字符,非贪婪方式。
        {n} 精准匹配n个前面的表达式。
        {n,m} 匹配n到m次由前面的正则表达式定义的片段,贪婪方式
        a|b 匹配a或者b。
        () 匹配括号内的表达式,也表示一个组

        模块和包

        我们今天来讲解一下模块和包,模块我们已经知道是什么东西了,我们现在来看看这个包是个什么? 我说的包可不是女同胞一看见就走不动的包,而是程序中一种组织文件的形式.
        ?
        只要文件夹下含有__init__.py文件就是一个包,包是干什么的呢?
        ?
        回想一下,之前我们没有学习模块的时候将一个整体的功能写入到文件中,为了能够充分的将某个功能进行重用 我们使用了模块,但是慢慢的模块就会越来越多.我们想提高程序的结构性可维护性,就使用包将模块进行统一管理
        ?
        包能够管理多个模块,我们想要使用包里的模块怎么办呢?
        ?
        使用import 和from xx import xx 现有如下结构
        ?
        bake            
        ?
           ├── __init__.py      
        ?
           ├── api              
        ?
               ├── __init__.py
        ?
               ├── policy.py
        ?
               └── versions.py
        ?
         ├── cmd            
        ?
           ├── __init__.py
        ?
           └── manage.py
        ?
         └── db                
        ?
             ├── __init__.py
        ?
             └── models.py
        我们在bake同级创建一个test.py进行导入policy.py 我们使用模块的import的时候只能将api添加到sys.path的路劲中,我们来看看包使用import导入
        ?
        import bake.api.policy
        bake.api.policy.get()
        导入的太长了下边使用的时候还需要在重复写一遍,我们可以使用as起别名
        ?
        import bake.api.policy as p
        p.get()
        这样的操作只支持包,普通的文件夹无效,有人一定在想我把bake拿过来然后一层一层的打开那拿工具就可以了
        ?
        import bake
        bake.api.policy.get()
        不好使,这样导入是只将policy导入了,有人想怎么将api包下的模块全部导入不要急,先说单独导入的方式
        ?
        咱们能够使用import进行导入,在来看看from的导入方式
        ?
        from bake.api import policy
        policy.get()
        from bake import api
        print(api.versions.name)
        还是不好使,通过这两个我们能够感觉都导入的时候指定要导入的内容,不能再导入后在进行开箱子
        ?
        我们现在说了单独导入一个模块,现在来说道说道怎么导入某个包下的所有模块,想要导入某个包下的所有的模块 我们就需要在包中的__init__.py做点手脚
        ?
        bake包下的__init__.py
        from . import api
        .是当前路径,因为from的时候不能空着
        ?
        api包下的__init__.py
        from . import policy
        我们将包下的__init__配置好,然后在test.py进行导入
        ?
        import bake
        bake.api.policy.get()
        又好使了,这是为什么呢?我们import导入bake这个包,因为bake是一个文件夹不能进行任何操作,就让__init__.py代替它 去将api这包中的模块导入,api也是一个文件夹不能操作就需要让api下边的__init__.py去找api下边的两个模块
        ?
        这个和公司的上下级关系一样,打比方现在test.py就是一个ceo要和policy这个小员工谈话,ceo先把这个想法人事经理,人事经理就是 bake这个包,人事经理通知人事让人事查找一下policy在那个部门,人事查到后通知部门的负责人,部门的负责人在通知部门的主管,主管告诉policy这个员工, 说ceo要找你,部门的主管带着policy去找人事,人事带着policy,人事然后在带着policy去找ceo.最后成功的和ceo进行了一番交流
        ?
        如果在传达的时候中间一个环节忘记传递了,policy就不知道ceo在找他,ceo等了好久不来ceo就生气报错了
        ?
        使用的时候需要注意: 有的同学,想在policy文件中导入versions就是直接使用import,在policy文件使用没有问题,很美,很高兴.但是在test.py执行的时候就会报错 因为我们在test.py中执行的import versions 相当于在test.py文件进行查找,肯定不会找到,我们需要在policy文件中向sys.path添加了当前的路劲就可以了 具体操作如下:
        ?
        import os
        import sys
        sys.path.insert(os.path.dirname(__file__)
        __file__获取的是当前文件的路径,这样我们就能在test中正常使用了,我们使用from也能够将某个包下所有的模块全都导入 比如我们现在想将cmd包下的所有的模块导入需要在bake包下的__init__.py进行设置
        ?
        from . import *
        我们需要在api包下设置__init__.py
        ?
        __all__ = ["policy","versions"]

        from . import policy
        from . import versions
        我们需要在db包下设置__init__.py
        ?
        __all__ = ["models"]

        from . import models
        我们需要在cmd包下设置__init__.py
        ?
        __all__ = ["manage"]

        from . import manage
        以上两种推荐使用下from . import manage 灵活,可读性高
        ?
        test.py调用如下:
        ?
        from bake.api import *
        print(versions.name)
        policy.get()
        ?
        from bake.db import *
        models.register_models(123)
        ?
        from bake.cmd import *
        print(manage.name)
        在使用import有个注意点,python2中如果import包,没有__init__.py文件就会报错 python3 import没有__init__.py文件的包不会报错 from import 包或者模块(在import后边不能在进行.操作)
        ?
        路径: 绝对路径:从最外层(bake)包.查找的就是绝对路径 相对路径:.就是相对路径, ..是上一级目录 例如:我们在bake/api/version.py中想要导入bake/cmd/manage.py
        ?
        # 绝对路径:
        from bake.cmd import manage
        manage.main()
        ?
        #相对路径:
        from ..cmd import manage
        manage.main()
        注意在使用相对路径的时候一定要在于bake同级的文件中测试 我们需要在和bake同级的test.py中测试
        ?
        from bake.cmd import manage
        ?

         

        logging日志模块

        我们来说一下这个logging模块,这个模块的功能是记录我们软件的各种状态,你们现在和我一起找到红蜘蛛的那个图标,然后右键找一找是不是有个错误日志.其实每个软件都是有错误日志的,开发人员可以通过错误日志中的内容对他的程序进行修改
        ?
        这只是一种应用场景,有的还会将日志用于交易记录.比如你给我转账应该做记录吧,
        ?
        我们使用的信用卡,每消费的一笔都会记录,我们来看看这个日志怎么用?
        ?
        我们先来看一下函数式简单配置
        ?
        import logging  
        logging.debug(‘debug message‘)  
        logging.info(‘info message‘)  
        logging.warning(‘warning message‘)  
        logging.error(‘error message‘)  
        logging.critical(‘critical message‘)
        默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING
        ?
        (日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),
        ?
        默认的日志格式为日志级别:Logger名称:用户输出消息。
        ?
        我们自己用函数写的这个可以正常使用但是不够灵活,我们看看这个灵活的
        ?
        灵活配置日志级别,日志格式,输出位置:
        ?
        import logging  
        logging.basicConfig(level=logging.DEBUG,  
                           format=‘%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s‘,  
                           datefmt=‘%a, %d %b %Y %H:%M:%S‘,  
                           filename=‘/tmp/test.log‘,  
                           filemode=‘w‘)  
        ?
        logging.debug(‘debug message‘)  
        logging.info(‘info message‘)  
        logging.warning(‘warning message‘)  
        logging.error(‘error message‘)  
        logging.critical(‘critical message‘)
        basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:
        ?
        filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
        filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
        format:指定handler使用的日志显示格式。
        datefmt:指定日期时间格式。
        level:设置记录日志的级别
        stream:用指定的stream创建StreamHandler。可以指定输出到
        sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
        format参数中可能用到的格式化串:
        ?
        %(name)s Logger的名字
        %(levelno)s 数字形式的日志级别
        %(levelname)s 文本形式的日志级别
        %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
        %(filename)s 调用日志输出函数的模块的文件名
        %(module)s 调用日志输出函数的模块名
        %(funcName)s 调用日志输出函数的函数名
        %(lineno)d 调用日志输出函数的语句所在的代码行
        %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
        %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
        %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
        %(thread)d 线程ID。可能没有
        %(threadName)s 线程名。可能没有
        %(process)d 进程ID。可能没有
        %(message)s用户输出的消息
        logger对象配置
        ?
        import logging
        ?
        logger = logging.getLogger()
        # 创建一个handler,用于写入日志文件
        fh = logging.FileHandler(‘test.log‘,encoding=‘utf-8‘)
        ?
        # 再创建一个handler,用于输出到控制台
        ch = logging.StreamHandler()
        formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)
        ?
        fh.setLevel(logging.DEBUG)
        ?
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)
        logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
        logger.addHandler(ch)
        ?
        logger.debug(‘logger debug message‘)
        logger.info(‘logger info message‘)
        logger.warning(‘logger warning message‘)
        logger.error(‘logger error message‘)
        logger.critical(‘logger critical message‘)
        logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过
        ?
        fh.setLevel(logging.Debug)单对文件流设置某个级别。
        ================================================================
        import logging
        ?
        logger = logging.getLogger()
        # 创建一个handler,用于写入日志文件
        fh = logging.FileHandler(‘test.log‘,encoding=‘utf-8‘)
        ?
        # 再创建一个handler,用于输出到控制台
        ch = logging.StreamHandler()
        formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)
        ?
        fh.setLevel(logging.DEBUG)
        ?
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)
        logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
        logger.addHandler(ch)
        ?
        logger.debug(‘logger debug message‘)
        logger.info(‘logger info message‘)
        logger.warning(‘logger warning message‘)
        logger.error(‘logger error message‘)
        logger.critical(‘logger critical message‘)
        ?

        logging日志旗舰版

        """
        logging配置
        """
        ?
        import os
        import logging.config
        ?
        # 定义三种日志输出格式 开始
        ?
        standard_format = ‘[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]‘
                         ‘[%(levelname)s][%(message)s]‘ #其中name为getlogger指定的名字
        ?
        simple_format = ‘[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s‘
        ?
        id_simple_format = ‘[%(levelname)s][%(asctime)s] %(message)s‘
        ?
        # 定义日志输出格式 结束
        ?
        logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
        ?
        logfile_name = ‘all2.log‘  # log文件名
        ?
        # 如果不存在定义的日志目录就创建一个
        if not os.path.isdir(logfile_dir):
           os.mkdir(logfile_dir)
        ?
        # log文件的全路径
        logfile_path = os.path.join(logfile_dir, logfile_name)
        ?
        # log配置字典
        LOGGING_DIC = {
           ‘version‘: 1,
           ‘disable_existing_loggers‘: False,
           ‘formatters‘: {
               ‘standard‘: {
                   ‘format‘: standard_format
              },
               ‘simple‘: {
                   ‘format‘: simple_format
              },
          },
           ‘filters‘: {},
           ‘handlers‘: {
               #打印到终端的日志
               ‘console‘: {
                   ‘level‘: ‘DEBUG‘,
                   ‘class‘: ‘logging.StreamHandler‘,  # 打印到屏幕
                   ‘formatter‘: ‘simple‘
              },
               #打印到文件的日志,收集info及以上的日志
               ‘default‘: {
                   ‘level‘: ‘DEBUG‘,
                   ‘class‘: ‘logging.handlers.RotatingFileHandler‘,  # 保存到文件
                   ‘formatter‘: ‘standard‘,
                   ‘filename‘: logfile_path,  # 日志文件
                   ‘maxBytes‘: 1024*1024*5,  # 日志大小 5M
                   ‘backupCount‘: 5,
                   ‘encoding‘: ‘utf-8‘,  # 日志文件的编码,再也不用担心中文log乱码了
              },
          },
           ‘loggers‘: {
               #logging.getLogger(__name__)拿到的logger配置
               ‘‘: {
                   ‘handlers‘: [‘default‘, ‘console‘],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                   ‘level‘: ‘DEBUG‘,
                   ‘propagate‘: True,  # 向上(更高level的logger)传递
              },
          },
        }
        ?
        ?
        def load_my_logging_cfg():
           logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
           logger = logging.getLogger(__name__)  # 生成一个log实例
           logger.info(‘It works!‘)  # 记录该文件的运行状态
        ?
        if __name__ == ‘__main__‘:
           load_my_logging_cfg()
        ?

以上是关于python基础篇的主要内容,如果未能解决你的问题,请参考以下文章

Python代码阅读(第19篇):合并多个字典

Python代码阅读(第41篇):矩阵转置

Python代码阅读(第26篇):将列表映射成字典

Python代码阅读(第40篇):通过两个列表生成字典

Python代码阅读(第25篇):将多行字符串拆分成列表

Python代码阅读(第13篇):检测列表中的元素是否都一样