zoukankan      html  css  js  c++  java
  • Python成长之路 基础篇4

    基础篇4

    1、装饰器

    2、迭代器与生成器

    3、Json与pickle数据序列化

    4、内置方法

    一、装饰器

    装饰器:

    装饰器本质上就是函数,用于装饰其他函数,给其它函数附加一些本身所没有的功能

    1、装饰器遵循的一些原则

      1)不能够改变被修饰函数的源代码。

      2)不能够改变被修饰函数的调用方式。

      3)不能够改变函数执行的结果

    装饰器对于要装饰的函数来说就是相当于透明。 

    2、装饰器需要知道的一些知识

      1)函数即“变量”

      2)高阶函数

        a、把一个函数当做实参传递给另一个函数

        b、返回值中包含函数名

      3)嵌套函数

        a、在一个函数里面声明另外一个函数叫做嵌套函数

    可以说  高阶函数+嵌套函数 => 装饰器

    装饰器的列子:

    #装饰器的一个列子
    import time
    
    def func():
        time.sleep(2)
        print("This is a test")
    
    func()
    
    #现在有一个需求
    # 给上面的函数加一个计算时间的功能
    #使用装饰器
    
    #--------------------------------------------------------------
    #修改后的代码
    import time
    
    def timer(func):
        def wrapper():
            start_time = time.time()
            func()
            stop_time = time.time()
            print("test function run time is %s" % (stop_time - start_time))
        return wrapper   #返回的是wrapper函数名的在内存中的位置
    
    def func2():
        time.sleep(2)
        print("This is a test")
    
    func2 = timer(func2)  #相当于timer(func2) = wrapper = func2
    func2()
    
    #--------------------------------------------------
    #因为有Python的语法糖所以代码可以这样
    import time
    
    def timer(func):
        def wrapper():
            start_time = time.time()
            func()
            stop_time = time.time()
            print("test function run time is %s" % (stop_time - start_time))
        return wrapper
    
    @timer  #相当于func2 = timer(func2) = wrapper# 给那个函数加该功能就在这个函数上面加@(功能函数)
    def func2():
        time.sleep(2)
        print("This is a test")
    
    func2()
    #----------------------------------------
    #如果我们运行的函数有参数
    import time
    
    def timer(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            func(*args, **kwargs)
            stop_time = time.time()
            print("test function run time is %s" % (stop_time - start_time))
        return wrapper
    
    @timer  #相当于func2 = timer(func2)# 给那个函数加该功能就在这个函数上面加@(功能函数)
    def func2(arg):
        time.sleep(2)
        print("This is a test")
    
    func2('test')
    #这样不管我们传参的时候传几个参数都可以把给功能加到想要家的函数上
    #上面的列子中包含了高阶函数和嵌套函数
    
    #----------------------------------------------
    #上面的方法只能够在我们被装饰的函数没有返回值的情况下才行
    #当被修饰的函数中有返回值时那么上面的列子就有改变了原来函数的运行结果
    #下面的列子包含返回值
    import time
    
    def timer(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            te = func(*args, **kwargs)
            stop_time = time.time()
            print("test function run time is %s" % (stop_time - start_time))
            return te
        return wrapper
    
    @timer  #相当于func2 = timer(func2)# 给那个函数加该功能就在这个函数上面加@(功能函数)
    def func2():
        time.sleep(2)
        print("This is a test")
    
    @timer
    def func3(arg):
        time.sleep(2)
        print("This is a test,test results is %s" % arg)
        return "This test is func3"
    
    func2()
    print(func3('test2'))
    
    #下面一个关于给不同的函数提供不同的加工方式
    #test登录方式为local登录
    #test2登录方式为ladp
    name = "yang"
    passwd = "123"
    def attestation(arg):
        def out_attestation(func):
            def wrapper(*args, **kwargs):
                user_name = input("请输入用户名:")
                user_passwd = input("请输入该密码:")
                if arg == "att_local":
                    if user_name == name and user_passwd == passwd:
                        print(" welcome to login successfully")
                        return func(*args, **kwargs)
                    else:
                        print("The user name or password you entered is wrong")
                 if arg == "att_ldap":#因为是统一认证所以把密码和用户信息去掉了
                    # if user_name == name and user_passwd == passwd:
                    #     print(" welcome to login successfully")
                    #     return func(*args, **kwargs)
                    # else:
                    #     print("The user name or password you entered is wrong")
                    #这里把用户名和密码去掉了所以才有下面代码如果有的话下面代码就没了
                    print(" welcome to login successfully")
                    return func(*args, **kwargs)
            return wrapper
        return out_attestation
    
    @attestation('att_local') #相当于test = wrapper。 [test=attestation('att_local')(test)]
    def test():
        print("Welcome to test 1 system page")
    
    @attestation("att_ldap")#相当于test2 = wrapper
    def test2():
        print("Welcome to test 2 system page")
    
    test()
    test2()
    

      

    二、迭代器与生成器

    迭代器(iterator)

    迭代器对象从集合的第一个元素开始访问,直到所有元素被访问完结束。

    迭代器拥有两个基本的方法:__iter()__和__next()__

    在说迭代器之前我们先了解下和区分下这几个概念:iterable、iterator、itertion

    itertion:这个是迭代,也就是一个接一个。

    iterator:迭代器 ,需要满足以下条件:

      1、定义了__iter__方法,但是必须返回自身

      2、定义一个__next__方法,用来返回下一个值,且当没有数据时,抛出StopIteration可以保持当前状态。

    代码如下:

    li = [1, 3, 4, 6]
    it = iter(li)  #有iter()方法
    print(next(it))#有next()方法
    print(next(it))   #可以使用迭代器的方法iter.__next__()和next(iter)效果一样
    print(next(it))
    print(next(it))
    print(next(it))   #到这步时会出现报错
    
    Traceback (most recent call last):
      File "F:/python/day4/iter.py", line 7, in <module>
        print(next(it))
    StopIteration
    1
    3
    4
    6
    #上面是运行结果
    
    #因为只能迭代一次所以当会报错
    

      

    iterable:这个是可迭代对象,满足一下任意一个条件都是iterable

      1、可以for循环: for i in iterable

      2、可以按index索引的对象,也就是定义getitem方法,如list,str:

      3、定义iter方法。可以随意返回

      4、可以调用iter(obj)对象,并且返回一个iterator

    从上面我们可以知道

    迭代器一定是可迭代的对象。

    迭代器就是可迭代的,但是可迭代的不一定是迭代器,如str、list属于iterable但是不属于iterator

    li = [1, 3, 4, 6]
    it = iter(li)
    print(type(it))
    
    print('it.__iter__',it.__iter__)#有__iter__
    
    print('it.__next__',it.next) #有next
    
    print('it.__iter__() is it ',it.__iter__() is it ) #返回自己
    

    迭代器是当我们创建列表的时候里面元素过多的话这样就太占内存空间,这个时候我们就要使用迭代器这样就占用的内存少点。

    生成器

    在Python中,任何使用yield的函数的都被称为生成器(generator)。

    在python中 生成器也就是迭代器(iterator),生成器完全遵循迭代器的要求。

    生成器函数和跟普通函数不同的是,它把return换成yield,并且yield和return不能够共用。其中yield是一个语法糖。内部实现了迭代器协议,同时保持状态可以挂起。

    使用yield,可以让函数生成一个序列,该函数但会的对象类型是“generator”,通过该对象连续调用next()方法返回序列值。

    创建一个generator,有很多下面就是一个简单的列子

    list = [i*2 for i in range(10)]
    print(list) #结果为[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
    print("list", type(list)) #结果为list <class 'list'>
    
    ite = (i*2 for i in range(10))
    print(ite) #结果为<generator object <genexpr> at 0x0000015EE3E4F048>
    print("list", type(ite)) #结果为list <class 'generator'>

      可以看到我们只是把外面的[]换成了(),而[]表示生成的是list,而()表示生成的是generator。

    我们list答应出来的是每个元素,然而generator打印的是一个迭代器,这就是我们为什么说生成器就是迭代器。

    所以生成器我们可以用next(iter)方法把里面的元素一个一个打印出来,也可以使用iter.__next__()方法,一般我们不采用前面的方法获取元素,一般使用for循环来取元素,因为生成器属于可迭代对象。

    以下使用斐波那契数列:

    def fib(max):
        a, b, n = 0, 1, 0
        while n<max:
            print(b)
            a, b =b, a+b
            n+=1
    
    fib(8)
    #结果
    1
    2
    3
    5
    8
    13
    21
    
    #生成器函数实现斐波那契
    def fib(max):
        a, b, n = 0, 1, 0
        while n<max:
            yield b
            a, b =b, a+b
            n+=1
    
    print(fib(8))#结果为 <generator object fib at 0x00000235374FF048>
    #使函数成为一个生成器
    def fib(max):
        a, b, n = 0, 1, 0
        while n<max:
            yield b
            a, b =b, a+b
            n+=1
    f = fib(10)
    while True:  #用于捕捉异常
        try:
            print(next(f), end=" ")
        except StopIteration as e:
            print('Generator return value:', e.value)
            break
    
    #结果为0 1 1 2 3 5 8 13 21 34 Generator return value:None
    

     有上面可以知道当我们把函数做成一个生成器函数,那么当函数里面有循环的时候当我们遇到yield是就会停止运行。

    也就是说我们可以运行函数里面循环一次在出来运行别的函数一,。这样可以做一些别的事情。

    下面的列子是python单线程下实现多线程运行效果

    import time
    
    def consumer(cons_name):#消费者
        print("%s过来买大饼" % cons_name)
        while True:
            dabing = yield
    
            print("%s的大饼做好了,被%s买走了"% (dabing,cons_name))
    
    def product():#生产者
        cons = consumer("张三")
        cons2 = consumer("李四")
        cons.__next__()
        cons2.__next__()
        print("大饼师傅开始做大饼")
        for i in range(5):
            time.sleep(1.5)
            print("做了五个酸豆角馅的大饼")
            cons.send("酸豆角")
            cons2.send("酸豆角")
    
    product()
    #实现了单线程情况下实现并程运算
    

      

    三、Json与pickle数据序列化

    把变量从内存中变成可储存或可传输的过程就称之为序列化。在Python中称之为picking。

    序列化之后就可以存储到磁盘上,或通过网络传输到别的机器上。有序列化就有反序列化,把内容从序列化对象重新读取到内存的过程称之为反序列化。

    json

    序列化

    import json
    
    dic = {
        'name':'张三',
        'age':30
    }
    
    f = open('json.txt','w')
    f.write(json.dumps(dic))
    f.close()
    

      反序列化

    import json
    
    f = open("json.txt", 'r')
    
    data2 = json.load(f)
    
    f.close()
    

    pickle

    序列化

    import pickle
    
    dic = {
        'name':'张三',
        'age':30
    }
    
    f = open('json.txt','wb')
    f.write(pickle.dumps(dic))
    f.close()
    

      反序列化

    import pickle
    
    f = open("json.txt", 'rb')
    
    data2 = pickle.load(f)
    
    f.close()
    

      json和pickle的区别

    1、json只能处理简单的数据结构,而pickle能够处理所有的数据类型(函数等)。

    2、json用于多个语言之间的网络传输,pickle多用于Python程序对象持久化或Python程序之间的网络传输

    四、内置方法

    注:

    abs(): 对传入的参数,获取其绝对值

    >>> abs(-10)
    10
    >>> abs(10)
    10
    

      传入的参数只能是数值

    all(): 接受一个可迭代的对象,如果该对象中的所有元素为真,那么就返回True,反之返回False

    any(): 接受一个可迭代的对象,如果该对象中有一个元素为真,那么就返回True,反之返回False

    ascii(): 调用对象__repr__()方法,获取该对象的返回值

    bin(): 二进制

    oct(): 八进制

    hex():十六进制

    bool():判断传入的参数是True还是False,None,0,"",[],{},()这些参数为False

    bytes(): 将字符串转换为字节,传参的时候,第一个参数代表的是要转换那个字符串,第二个为按什么编码转换为字节

    str():字节转换为字符串,第一个参数是要转换的字节,第二个参数是按什么编码转换成字符串

    callable(): 判断对象是否可以被调用,能被调用的对象就是一个callable对象,

    chr(): unicode的转换,按照Unicode转换成字符。

    ord():  按照unicode转换成数字

    compile():  接收.py文件或字符串作为传入参数,将其编译成python字节码

    eval(): 执行python代码,并返回其执行结果。 e.g. eval("1+2+3")   eval("print(123)").   在接收用户输入时应避免使用eval,因为别有用心的用户可能借此注入恶意代码

    exec(): 执行python代码(可以是编译过的,也可以是未编译的),没有返回结果(返回None) e.g. exec(compile("print(123)","<string>","exec"))   exec("print(123)")

    dir(): 接收对象作为参数,返回该对象的所有属性和方法

    help(): 接收对象作为参数,更详细地返回该对象的所有属性和方法

    divmod(100,10) : 返回一个元组(10,0),第一个元素的100/10的商,第二个元素的100/10的余数 

    enumerate(): 接收序列化类型的数据,返回一个迭代器(对象). e.g. for i,item in enumerate(['one','two','three']): print(i,item)  打印1 'one' 换行2 'two'换行 3 'three'

    isinstance(object, class): 判断对象是否是某个类的实例. e.g. isinstance([1,2,3],list)

    filter(函数或者lambda表达式,可迭代的对象): 对可迭代对象中的每一个元素,将其作为实参传入函数(或lambda表达式),如果函数返回False,将该元素丢弃,如果函数返回True,将该元素添加到filter的返回值中。注意filter返回的是一个filter对象,实际应用中往往需要用list或tuple将其转换为列表或元组类型. e.g. list(filter(lambda a:a>1,[1,2,3])) 返回[2,3]

    map(函数或lambda表达式,可迭代的对象): 对可迭代的每一个元素,将其作为实参传入函数,将每一次调用函数返回的结果都添加到map的返回值中。e.g. tuple(map(lambda a:a+1,(1,2,3))) 返回(2,3,4)

    format(): 字符串格式化

    frozenset() : 转换为不可变的集合

    globals() : 返回一个字典,包括所有的全局变量与它的值所组成的键值对

    locals() :  返回一个字典,包括所有的局部变量与它的值所组成的键值对

    hash(): 对传入参数取哈希值并返回

    id():返回内存地址,可用于查看两个变量是否指向相同一块内存地址

    input('please input:') : 提示用户输入,返回用户输入的内容(不论输入什么,都转换成字符串类型)

    issubclass(subclass,class) :查看这个类是否是另一个类的派生类,如果是返回True,否则返回False

    len('string') :返回字符串长度,在python3中以字符为单位,在python2中以字节为单位

    max():接收序列化类型数据,返回其中值最大的元素

    min(): ..... 返回其中值最小的元素

    memoryview():  查看内存地址

    next() 

    iter()  

    object() 

    pow(x,y): 求次方,返回x**y的结果

    pow(x,y,z): 返回 x**y%z 的结果

    property(): 获取对象的所有属性

    range(): 获取随机数或随机字符 eg. range(10) 从0到10的随机数

    repr(): 执行传入对象中的_repr_方法

    reversed():对序列化类型数据反向排序,返回一个新的对象。注意与对象的reverse方法区别,后者是就地改变对象

    sorted(): 对序列化类型数据正向排序,返回一个新的对象。注意与对象的sort方法区别,后者是就地改变对象

    slice():对序列化类型数据切片,返回一个新的对象。eg. slice(起始下标,终止下标,步长),步长默认为1

    round() : 返回四舍五入后的结果

    int() :转换为整型

    list():转换为列表类型

    set(): 转换为集合类型

    str():转换为字符串类型

    tuple() : 转换为元组类型

    type(): 返回对象类型

    staticmethod() : 返回静态方法

    super(): 返回基类

    vars():返回当前模块中的所有变量

    zip():接收多个序列化类型的数据,对各序列化数据中的元素,按索引位置分类成一个个元组。

    eg. myList = list(zip([1,2,3],['a','b','c'])) 创建myList列表[(1,'a'),(2,'b'),(3,'c')]    

    mydic = dict(zip([1,2,3],['a','b','c'])) 创建mydic字典{1:'a',2:'b',3:'c'}

    l1 = [1,2,3]

    l2 = ['one','two','three']

    list(zip(l1,l2))  返回[(1,'one'),(2,'two'),'(3,'three')] 

  • 相关阅读:
    虚拟化技术总览
    UNIX环境高级编程笔记之高级I/O
    UNIX环境高级编程笔记之线程
    UNIX环境高级编程笔记之进程控制
    UNIX环境高级编程笔记之进程环境
    mysql中如何删除表上的索引?删除索引?
    linux环境中如何删除文件的前n行?
    linux环境中iostat命令的安装,解决-bash: iostat: command not found问题
    linux环境中安装iotop命令,解决-bash: iotop: command not found问题
    mysql初始化时报错bin/mysqld: error while loading shared libraries: libnuma.so.1: cannot open shared object file: No such file or directory的处理
  • 原文地址:https://www.cnblogs.com/yang-China/p/7927999.html
Copyright © 2011-2022 走看看