• python学习之路基础篇(第五篇)


    前四天课程回顾

    1.python简介

    2.python基本数据类型

    类:
      int:整型  | str:字符串 |  list:列表 |tuple:元组 |dict:字典 | set:集合
    对象:
      li = [11,22,33]   #列表的一个对象
      s = "MoHan"    #字符串的一个对象

    3.函数式编程 

    4.装饰器

    @装饰器函数名
    def func():
     pass
    其中@装饰器函数名,程序执行到此,会进行如下三步操作:
    1.将func当做参数进行传递给装饰器函数并执行 2.将装饰器函数的返回值重新赋值给func 3.执行func函数就相当于执行装饰器函数的返回值

    装饰器

    通过上一次课程的学习,我们已经知道了什么是装饰器,装饰器内部是如何运行的,上次课程我们说到函数可以被装饰器封装,并且通过作业的练习,已基本掌握简单装饰器的基本操作,我心里有个疑问,一个函数可以被多个装饰器装饰么?答案是肯定。

    #执行程序的开关
    USER_INFO = {}
    USER_INFO['is_login'] = False     #通过is_login的值来判断用户是否已经登录
    USER_INFO['user_type'] = 2       #通过user_type的值来判断用户是否是管理员
    #USER_INFO.get('is_login',None)
    
    def check_login(func):
        def inner(*args,**kwargs):
            if USER_INFO.get('is_login',None):
                ret = func(*args,**kwargs)
                return ret
            else:
                print('请登录')
        return inner
    
    def check_admin(func):
        def inner(*args,**kwargs):
            if USER_INFO.get('user_type',None) == 2:
                ret = func(*args,**kwargs)
                return ret
            else:
                print('您无权限进行此操作')
        return inner
    
    @check_login
    @check_admin
    def index():
        print('inex')
    
    index()    
    
    #双层装饰器的执行顺序:check_log-------check_admin-----index
    #装饰器还可有三层、四层......多层

    字符串格式化

    一、.python字符串格式化有两种方式:%  和 format

    This PEP proposes a new system for built-in string formatting operations, intended as a replacement for the existing '%' string formatting operator

    1.百分号方式

    用法:%[(name)][flags][width].[precision]typecode

      • (name)      可选,用于选择指定的key
      • flags          可选,可供选择的值有:
        • +       右对齐;正数前加正好,负数前加负号;
        • -        左对齐;正数前无符号,负数前加负号;
        • 空格    右对齐;正数前加空格,负数前加负号;
        • 0        右对齐;正数前无符号,负数前加负号;用0填充空白处
      • width         可选,占有宽度
      • .precision   可选,小数点后保留的位数
      • typecode    必选
        • s,获取传入对象的__str__方法的返回值,并将其格式化到指定位置
        • r,获取传入对象的__repr__方法的返回值,并将其格式化到指定位置
        • c,整数:将数字转换成其unicode对应的值,10进制范围为 0 <= i <= 1114111(py27则只支持0-255);字符:将字符添加到指定位置
        • o,将整数转换成 八  进制表示,并将其格式化到指定位置
        • x,将整数转换成十六进制表示,并将其格式化到指定位置
        • d,将整数、浮点数转换成 十 进制表示,并将其格式化到指定位置
        • e,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写e)
        • E,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写E)
        • f, 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位)
        • F,同上
        • g,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是e;)
        • G,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是E;)
        • %,当字符串中存在格式化标志时,需要用 %%表示一个百分号

    注意:python中百分号格式化是不存在自动将整数转换成二进制表示的方式

    #常用的%: %s :字符串  %d:数字    %f:浮点数

    tp1 = "i am %s age %d" %("alex",19)
    tp2 = "i am %(name)s age %(age)d" %{"name":"alex","age":19}
    tp3 = "percent %.2f" %99.9762
    tp4 = "percent %(pp).2f" %{"pp":99.9762}
    tp5 = "percent %.2f%%" %(99.9762,)
    tp6 = "i am %s" %('alex')
    print(tp1)
    print(tp2)
    print(tp3)
    print(tp4)
    print(tp5)
    print(tp6)
    程序执行结果如下:
    i am alex age 19
    i am alex age 19
    percent 99.98
    percent 99.98
    percent 99.98%
    i am alex  

    2.Format方式

    [[fill]align][sign][#][0][width][,][.precision][type]

      • fill           【可选】空白处填充的字符
      • align        【可选】对齐方式(需配合width使用)
        • <,内容左对齐
        • >,内容右对齐(默认)
        • =,内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
        • ^,内容居中
      • sign         【可选】有无符号数字
        • +,正号加正,负号加负;
        •  -,正号不变,负号加负;
        • 空格 ,正号空格,负号加负;
      • #            【可选】对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显示
      • ,            【可选】为数字添加分隔符,如:1,000,000
      • width       【可选】格式化位所占宽度
      • .precision 【可选】小数位保留精度
      • type         【可选】格式化类型
        • 传入” 字符串类型 “的参数
          • s,格式化字符串类型数据
          • 空白,未指定类型,则默认是None,同s
        • 传入“ 整数类型 ”的参数
          • b,将10进制整数自动转换成2进制表示然后格式化
          • c,将10进制整数自动转换为其对应的unicode字符
          • d,十进制整数
          • o,将10进制整数自动转换成8进制表示然后格式化;
          • x,将10进制整数自动转换成16进制表示然后格式化(小写x)
          • X,将10进制整数自动转换成16进制表示然后格式化(大写X)
        • 传入“ 浮点型或小数类型 ”的参数
          • e, 转换为科学计数法(小写e)表示,然后格式化;
          • E, 转换为科学计数法(大写E)表示,然后格式化;
          • f , 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
          • F, 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
          • g, 自动在e和f中切换
          • G, 自动在E和F中切换
          • %,显示百分比(默认显示小数点后6位)

    简单小练习:

    s1 = "abcdefg{0}abcdefg{0}123{1}".format('111','7777')
    #对号入座 {0}---111,{1}----7777
    print(s1)
    s2 = "-----{name:s}_____{age:d}------{name:s}".format(name='alex',age=12)
    #根据名称来进行赋值,可以不按照顺序
    print(s2)
    s3 = "---{:*^20s}______{:+d}------{:x}".format('alex',23,45)
    #*20:占据20个位置,如果传入的参数不足20个字符用*进行填充
    #^:居中显示 < 左对齐 >右对齐
    #s:字符串 d:数字
    #+:正数前面+,负数前面加符号
    #x:将十进制自动转换成十六进制数字表示然后进行格式化  :X :b(二进制) :o(八进制)
    print(s3)
    #
    # 程序执行结果如下:
    # abcdefg111abcdefg1111237777
    # -----alex_____12------alex
    # ---********alex********______+23------2d
    

    format实例

    tp1 = "i am {}, age {},{}".format("alex",38,'sir')
    #按顺序进行赋值,{}没有指定要传入的数据类型,可以将传入的任意数值类型进行格式化
    tp2 = "i am {},age {},{}".format(*["seven",38,'sir'])
    #*[]:将列表中的元素按顺序进行赋值,如果不加*则表示整个列表是一个元素,如果直接传入则会报错,所以传入的参数要
    #>=前面预留的空间的个数
    tp3 = "i am {0},age {1},really {0}".format('seven',18)
    tp4 = "i am {0},age {1},really {0}".format(*['seven',18])
    tp5 = "i am {name},age {age},really {name}".format(name="seven",age=18)
    tp6 = "i am {name},age {age},really {name}".format(**{"name":"seven",'age':18})
    tp7 = "i am {0[0]},age {0[1]},really {0[2]}".format([1,2,3],[11,22,33])
    tp8 = "i am {:s},age {:d}".format(*['seven',18])
    tp9 = "i am {:s},age {:d},money {:f}".format('seven',18,18888.111)
    tp10 = "i am {name:s},age {age:d}".format(name='seven',age=18)
    tp11 = "i am {name:s},age {age:d}".format(**{'name':'seven','age':18})
    tp12 = "numbers:{:b},{:o},{:x},{:X},{:%} ".format(15,23,34,56,78,12.788999,23)
    tp13 = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
    tp14 = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)
    print(tp1)
    print(tp2)
    print(tp3)
    print(tp4)
    print(tp5)
    print(tp6)
    print(tp7)
    print(tp8)
    print(tp9)
    print(tp10)
    print(tp11)
    print(tp12)
    print(tp13)
    print(tp14)
    程序执行结果如下:
    i am alex, age 38,sir
    i am seven,age 38,sir
    i am seven,age 18,really seven
    i am seven,age 18,really seven
    i am seven,age 18,really seven
    i am seven,age 18,really seven
    i am 1,age 2,really 3
    i am seven,age 18
    i am seven,age 18,money 18888.111000
    i am seven,age 18
    i am seven,age 18
    numbers:1111,27,22,38,7800.000000% 
    numbers: 1111,17,15,f,F, 1500.000000%
    numbers: 1111,17,15,f,F, 1500.000000%
    

    更多格式化操作请参考:https://docs.python.org/3/library/string.html

    生成器和迭代器

     1.迭代器

    迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件

    特点:

    • 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
    • 不能随机访问集合中的某个值 ,只能从头到尾依次访问
    • 访问到一半时不能往回退
    • 便于循环比较大的数据集合,节省内存

    2.生成器

    一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);如果函数中包含yield语法,那这个函数就会变成生成器

    #生成器的定义:生成器也是一个函数,一个函数中如果出现yield则函数就变成生成器
    #具有生成某种数据的能力
    #生成器的本质:yield  
    
    def func():
        yield  1
        yield  2
        yield  3
    ret = func()
    for i in ret:
        print(i)
        
    #程序执行结果如下:
    1
    2
    3
    

    上述代码中:func是函数称为生成器,当执行此函数func()时会得到一个迭代器。  

    # def func():
    #     print(1111)
    #     yield  1
    #     print(2222)
    #     yield  2
    #     print(3333)
    #     yield  3
    # ret = func()
    # r1 = ret.__next__()  #进入函数找到yield,获取yield后面的值1
    # print(r1)
    # r2 = ret.__next__() #进入函数找到yield,获取yield后面的值2
    # print(r2)
    # r3 = ret.__next__() #进入函数找到yield,获取yield后面的值3
    # print(r3)
    # r4 = ret.__next__()
    # print(r4)
    
    # 程序执行结果如下:
    # 1111
    # 1
    # 2222
    # 2
    # 3333
    # 3
    

    3.实例

    利用生成器自定义myrange

    def myrange(arg):
        start = 0
        while True:
            if start > arg:
                return
            yield start
            start += 1

    利用迭代器访问myrange

    ret = myrange(3)
    r = ret.__next__()
    print(r)
    r = ret.__next__()
    print(r)
    r = ret.__next__()
    print(r)
    r = ret.__next__()
    print(r)  

    递归

    引入:函数的调用

    #函数的调用
    #执行a()时,a去调用函数b,执行函数b()时,b去调用函数c,执行函数c时,c去调用函数d,
    #执行d()时,返回给123
    def d():
        return '123'
    
    def c():
        r = d()
        return r
    
    def b():
        r = c()
        return r
    
    def a():
        r = b()
        return r
    
    ret = a()
    print(ret)
    程序执行结果如下:
    123
    

    从上面的代码我们可以看出,执行一个函数a()时,a去调用函数b,而执行函数b时,b又去调用函数c,这个过程称之为函数的调用。函数在执行的时候可以去调用别的函数,是不是也可以调用自身呢,答案是可以的,执行函数的时候去调用自身来进行执行的过程即是递归,说白了,递归就是函数自己调用自己的过程。

    #递归函数
    def func(n):
        n += 1
        if n > 4:
            return 'end'
        return func(n)
    
    r = func(1)
    print(r)
    
    #程序执行结果如下:
    end 

    模块

    模块是一个功能的集合

    类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。

    模块的分类:

    • 自定义模块:自己编写的模块 
    • 内置模块(python自带的os sys file json)
    • 第三方模块

    模块的导入:

    Python之所以应用越来越广泛,在一定程度上也依赖于其为程序员提供了大量的模块以供使用,如果想要使用模块,则需要导入。导入模块有一下几种方法:

    import module  #导入模块下的全部模块
    from module.xx.xx import *  #导入模块下的全部模块
    from module.xx.xx import xx  #导入某块下的指定模块
    from module.xx.xx import xx as rename   #导入指定模块并给他设置别名 
    

    导入模块其实就是告诉Python解释器去解释那个py文件

    • 导入一个py文件,解释器解释该py文件
    • 导入一个包,解释器解释该包下的 __init__.py 文件 

    那么问题来了,导入模块时是根据那个路径作为基准来进行的呢?即:sys.path

    import sys
    print(sys.path)
    输出结果:
    ['D:\PythonS13\Day5\class', 'D:\PythonS13', 'C:\python35\python35.zip', 'C:\python35\DLLs', 'C:\python35\lib', 'C:\python35', 'C:\python35\lib\site-packages']
    

    如果sys.path路径列表没有你想要的路径,可以通过 sys.path.append('路径') 添加。

    import sys
    import os
    project_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(project_path)    

    自定义模块

    自定义模块一般都是自己写的可以是一个独立的.py文件,也可以是一个文件夹,但是普通的文件夹并不是一个模块,一个模块必须是包含__init__的目录。

    自定义一个名为“自定义模块_8”的模块,然后在“调用模块的函数_8”程序里面调用,如果要使用模块里面方法,直接使用模块名 .方法即可

     

    内置模块

    内置模块是Python自带的功能,在使用内置模块相应的功能时,需要【先导入】再【使用】

    1.sys

    用于提供对Python解释器相关的操作:

    sys.argv           命令行参数List,第一个元素是程序本身路径
    sys.exit(n)        退出程序,正常退出时exit(0)
    sys.version        获取Python解释程序的版本信息
    sys.maxint         最大的Int值
    sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    sys.platform       返回操作系统平台名称
    sys.stdin          输入相关
    sys.stdout         输出相关
    sys.stderror       错误相关
    

    实例:进度百分比

    import sys
    import time
    
    def view_bar(num, total):
        rate = float(num) / float(total)
        rate_num = int(rate * 100)
        #r = '
    %d%%' % (rate_num, )
        r = '
    [%-100s]%d%%' % ('=' * rate_num, rate_num,)
        sys.stdout.write(r)
        sys.stdout.flush()
    
    if __name__ == '__main__':
        for i in range(0, 101):
            time.sleep(0.1)
            view_bar(i, 100)

    2.os

    用于提供系统级别的操作:

    os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径
    os.chdir("dirname")         改变当前脚本工作目录;相当于shell下cd
    os.curdir                   返回当前目录: ('.')
    os.pardir                   获取当前目录的父目录字符串名:('..')
    os.makedirs('dir1/dir2')    可生成多层递归目录
    os.removedirs('dirname1')   若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    os.mkdir('dirname')         生成单级目录;相当于shell中mkdir dirname
    os.rmdir('dirname')         删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
    os.listdir('dirname')       列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    os.remove()                 删除一个文件
    os.rename("oldname","new")  重命名文件/目录
    os.stat('path/filename')    获取文件/目录信息
    os.sep                      操作系统特定的路径分隔符,win下为"\",Linux下为"/"
    os.linesep                  当前平台使用的行终止符,win下为"	
    ",Linux下为"
    "
    os.pathsep                  用于分割文件路径的字符串
    os.name                     字符串指示当前使用平台。win->'nt'; Linux->'posix'
    os.system("bash command")   运行shell命令,直接显示
    os.environ                  获取系统环境变量
    os.path.abspath(path)       返回path规范化的绝对路径
    os.path.split(path)         将path分割成目录和文件名二元组返回
    os.path.dirname(path)       返回path的目录。其实就是os.path.split(path)的第一个元素
    os.path.basename(path)      返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素
    os.path.exists(path)        如果path存在,返回True;如果path不存在,返回False
    os.path.isabs(path)         如果path是绝对路径,返回True
    os.path.isfile(path)        如果path是一个存在的文件,返回True。否则返回False
    os.path.isdir(path)         如果path是一个存在的目录,则返回True。否则返回False
    os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
    os.path.getatime(path)      返回path所指向的文件或者目录的最后存取时间
    os.path.getmtime(path)      返回path所指向的文件或者目录的最后修改时间
    

    第三方模块 

    下载安装有两种方式:

    通过第三方的集成安装

    yum
    pip
    apt-get
    ...

     通过源码安装

    下载源码
    解压源码
    进入目录
    编译源码    python setup.py build
    安装源码    python setup.py install 

     注:在使用源码安装时,需要使用到gcc编译和python开发环境

     

    yum install gcc
    yum install python-devel
    或
    apt-get python-dev
    

     

    下面我们以安装request来进行说明

    requests

    Python标准库中提供了:urllib等模块以供Http请求,但是,它的 API 太渣了。它是为另一个时代、另一个互联网所创建的。它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务

    import urllib.request
    
    f = urllib.request.urlopen('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
    result = f.read().decode('utf-8')
    
    import urllib.request
    
    req = urllib.request.Request('http://www.example.com/')
    req.add_header('Referer', 'http://www.python.org/')
    r = urllib.request.urlopen(req)
    
    result = f.read().decode('utf-8')
    

    注:更多见Python官方文档:https://docs.python.org/3.5/library/urllib.request.html#module-urllib.request

    Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,从而使得Pythoner进行网络请求时,变得美好了许多,使用Requests可以轻而易举的完成浏览器可有的任何操作。

    1、安装模块

    python - m  pip install requests
    2、使用模块
    # 1、无参数实例
     
    import requests 
    ret = requests.get('https://github.com/timeline.json') 
    print(ret.url)
    print(ret.text)
     
    # 2、有参数实例
     
    import requests
     
    payload = {'key1': 'value1', 'key2': 'value2'}
    ret = requests.get("http://httpbin.org/get", params=payload)
     
    print(ret.url)
    print(ret.text)
    复制代码
    # 1、无参数实例
     
    import requests
     
    ret = requests.get('https://github.com/timeline.json')
     
    print(ret.url)
    print(ret.text)
     
     
     
    # 2、有参数实例
     
    import requests
     
    payload = {'key1': 'value1', 'key2': 'value2'}
    ret = requests.get("http://httpbin.org/get", params=payload)
     
    print(ret.url)
    print(ret.text)
    # 1、基本POST实例
     
    import requests
     
    payload = {'key1': 'value1', 'key2': 'value2'}
    ret = requests.post("http://httpbin.org/post", data=payload)
     
    print(ret.text)
     
     
    # 2、发送请求头和数据实例
     
    import requests
    import json
     
    url = 'https://api.github.com/some/endpoint'
    payload = {'some': 'data'}
    headers = {'content-type': 'application/json'}
     
    ret = requests.post(url, data=json.dumps(payload), headers=headers)
     
    print(ret.text)
    print(ret.cookies)
    
    requests.get(url, params=None, **kwargs)
    requests.post(url, data=None, json=None, **kwargs)
    requests.put(url, data=None, **kwargs)
    requests.head(url, **kwargs)
    requests.delete(url, **kwargs)
    requests.patch(url, data=None, **kwargs)
    requests.options(url, **kwargs)
     
    # 以上方法均是在此方法的基础上构建
    requests.request(method, url, **kwargs)
    

    更多requests模块相关的文档见:http://cn.python-requests.org/zh_CN/latest/  

      

     

     

     

     
  • 相关阅读:
    elemen-ui表格多选,分页保持勾选状态的实现
    element-ui中的change事件传递多个参数的方法
    vue中访问不存在路由默认跳转404页面实现方法
    IntelliJ IDEA 汉化包
    vue 移动端项目用手机预览调试
    vue 中使用 rem
    vue中配置axios.js文件,发送请求
    vue中axios的使用
    爬楼梯
    不同路径
  • 原文地址:https://www.cnblogs.com/yamei/p/5562426.html
Copyright © 2020-2023  润新知