zoukankan      html  css  js  c++  java
  • 函数+装饰器+迭代器+生成器

    闭包函数
    闭包:定义在内网函数,包含对外部作用域而非全局作用域
    范围:一个函数套用1或n个函数
    from urllib.request import urlopen  #urlopen模块 作用:爬网页
    #闭包函数,内部get函数调用外部page函数
    def page(url):                                  #调用url
        def get():                                  #下载
            return urlopen(url).read()              #爬网页
        return get                                  #返回url值
    baidu=page("http://www.baidu.com")              #函数page的值,手动写的url(url可变)
    #print(baidu.__closure__[0].cell_contents)      #看oldboy函数包裹的元素
    #print(baidu.__closure__)                       #看oldboy函数有几个值
    print(baidu())                                  #显示百度网页
     
    #如下效果相同,不是闭包函数,不灵活,(不能写baidu=page("http://www.baidu.com")的形式,)
    def get(url):                       #下载
        return urlopen(url).read()
    print(get("http://www.baidu.com")) #定义url    
    #显示返回网页
    
    装饰器
    装饰器:装饰代码
    必须遵守2个原则
    最好不要修改源代码
    最好不要修改调用方式
    调用方式
    functools模块(保存源代码的注释,更新到装饰后的程序)
    import time
    def timer(func):                    #func相等于index
        def wrapper(*args,**kwargs):    #wrapper等于indiex 所有要赋值
            start_time=time.time()      #计算第一次执行时间
            res=func(*args,**kwargs)    #定义func的值给res
            stop_time=time.time()       #计算第二次执行时间
            print("run time is %s" %(start_time-stop_time))
            return res                   #定义子函数的返回值
        return wrapper                  #返回子函数的值
    @timer                  #index=timer(index) 注:把正下方的函数值给timer
    def index():
        time.sleep(3)                    #沉睡3秒
        print("welcome to index")
    index()    #显示是装饰后的值
    #3秒后显示如下
    #welcome to index
    #run time is -3.0002331733703613
    (函数增加功能,用户认证通过后执行函数,否则提示报错信息)
    def Gavin(guolm):
        aa = ["guolm", "admin_1234"]
        def wrapper(*args,**kwargs):
            select= input("peales your writer your user>>>:")
            if select==aa[0]:
                print("ok")
                select1 = input("peales your writer your pass>>>:")
                if select1 ==aa[1]:
                    res=guolm(*args,*kwargs)
                    return res
                else:
                    print("pass error")
            else:
                print("user error")
        return wrapper
    @Gavin
    def guolm():
        print("hello man")
        return guolm
    guolm()                            #相当guolm= Gavin(guolm) 获取
    
    用户认证+第二次不需要输入认证信息
    logon_user={"user":None,'STATUS':False}
    def auth2(driver="file"):
        def ahth(func):
            def wrapper(*args,**kwargs):
                if driver=="file":
                    if logon_user["user"] and logon_user["status"]:   #如果user有值并且statis是True,继续执行,#注释第一遍执行时,值不存在,所以执行else,第二次循环则成立
                        res=func(*args,**kwargs)                      #定义了函数func可n个元组,列表和n个字典
                        return res                                    #第三层函数的返回值
                    else:
                        name=input(">>>:")
                        password=input(">>>:")
                        if name == "egon" and password == "123":    #如果认证成立继续执行
                            logon_user["user"]="egon"               #改变logon_user的user值, 为上个if判断做铺垫
                            logon_user["status"]=True               #改变logon_user的status值,为上个if判断做铺垫
                            res=func(*args,**kwargs)
                            return res                              #第三层函数的返回值
                        else:
                            print("error")
                elif driver == "mysql":
                    print("show mysql")
                    return func(*args,**kwargs)
                elif driver=="ldap":
                    print("=====ldap认证")
                else:
                    print("无效认证")
            return wrapper
        return  ahth
    @auth2("file")                                  #index函数值为file,执行如下函数#相当于调用auth2下的ahth下的wrapper函数
    def index():
        print("welcome to index page")
    @auth2(driver="mysql")                          #home("egon")函数值为mysql,执行如下函数
    def home(name):                                 #相当于调用auth2下的ahth下的wrapper函数
        print("%s welcome to home page" %name)      #name是 输入home("egon")的传参 就是egon
    index()         #wrapper
    home("11")       #输入11也能实现 有点不懂
    
    迭代器
    为什么要有迭代器?    对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式
    迭代的概念:    每次执行的结果作为下一次迭代的初始值
    优点 : 提供一种不依赖下标的迭代方式,且迭代器更省内存空间(因为每次读取1行)
    缺点:  不能获取迭代器对象的长度,且不如序列类型取值灵活,是一次性的,只能向后取值,不能向前
    for循环也属于迭代器
    
    可迭代的对象: 能执行.__iter__()方法为True
    迭代器对象:能执行.__iter__()方法为True和执行__next__()是方法为True
    可迭代对象: 只有__iter方法, 执行该方法可得到迭代器对象,只有可使用__next__方法
    
    #数字不是迭代对象
    #只是文件是迭代器,其他都可迭代对象
    
    [1,2].__iter__()                #列表
    "hello".__iter__()              #字符串
    (1,2,).__iter__()               #元组
    {"a":"1","b":"2"}.__iter__()    #列表
    {1,2,3}.__iter__()              #集合
    
    f=open("a.txt","w")          #文件
    f.__iter__() 
    #判断是否为可迭代对象
    print(isinstance([1,2],Iterable))                 #返回True
    print(isinstance("hello",Iterable))               #返回True
    print(isinstance((1,2,),Iterable))                #返回True
    print(isinstance({"a":"1","b":"2"},Iterable))    #返回True
    print(isinstance({1,2,3},Iterable))                #返回True
    print(isinstance(f,Iterable))                #返回True
    #判断是否为迭代器对象
    print(isinstance([1,2],Iterator))                 #返回False
    print(isinstance("hello",Iterator))               #返回False
    print(isinstance((1,2,),Iterator))                #返回False
    print(isinstance({"a":"1","b":"2"},Iterator))    #返回False
    print(isinstance({1,2,3},Iterator))               #返回False
    print(isinstance(f,Iterator))                      #返回True
    
    例如:
    iter确定是迭代器  next取出值
    i=[1,2,4].__iter__()
    
    print(i)
    print(i.__next__())                            #列表的值有3个 执行next每次只能取一个值
    print(i.__next__())
    print(i.__next__())
    print(i.__next__())                            #因为只有3个值,执行4个会报错
    #####
    <list_iterator object at 0x0000003FC1E0E2E8>   #迭代器的内存地址 
    1
    2
    4
    或
    dic={"a":1,"b":2,"c":3,}
    i=dic.__iter__()            #确定dic可迭代
    while True:
        try:                    #尝试实现如下信息
            key=i.__next__()    #迭代i的值给key
            print(dic[key])
        except StopIteration:   #except是抛出异常 遇到异常StopIteration,执行break
            break
     
    
    生成器yield
    yield的功能:
    1    使用yield把函数变成迭代器 ,(相当于为函数封装好__iter__和__next__)
    2    yield能返回多次,每次返回都会讲函数暂停,下一次next会从上一次暂停的位置继续执行,而return返回一次值,函数就终止
    
    生成器操作
    def foo():
        print("first")
        yield 1         #之前的值
        print("second")
        yield 2
        print("fifth")
    g=foo()
    print(g)            #看g的内存地址
    print(next(g))
    print(next(g))
    #print(next(g))   #因为fifth没有加生成器yield 使用迭代器执行会保存
    #或如下执行
    for i in g:
        print(i)
    
    生成器中使用计数器
    def counter(n):
        print("start")
        i = 0
        while i< n :
            yield i
            i+=1
        print ("end")
    g=counter(3)        #g是函数调用
    
    for i in g:          #for循环显示生成器的值
        print(i)
    #显示
    start
    0
    1
    2
    end
    显示文件,执行内容
    #1,创建a.txt文件
    #2执行python
    #3,在db文件中输入值,最后一行开始计算,包含python的行会显示,不包含的行不显示
    import time             #时间模块
    def tail(file):
        with open(file,encoding="utf-8") as f:  #读取file(函数1定义的file),读取为utf-8
            f.seek(0,2)                         #文件最尾部操作
            while True:
                line=f.readline().strip()
                if line:                      #如果line值成立,则...
                    yield line                #返回line值,并再次从新执行函数
                else:
                    time.sleep(0.2)           #沉睡0.2秒
    def grep(pattern,lines):                  #定义了2个参数
        for i in lines:
            if pattern in i:                  #pattern相当于python
                print(i)
    g=grep("python",tail("a.txt"))          #g= grep函数的第二个参数是tail函数和tail调用文件,a.txt可改
    for i in g:                             #循环显示值
        print(i)

    1.    名称空间与作用域

    1. 全局作用域:      

        范围: 内置名称空间,全局名称空间
        有效期:全局有效,在任何地方都可用, 不删除长期有效
        查找顺序:         局部名称空间 -->全局名称空间-->内置名称空间
        x=1000
        def func():
        x=1
        def f1():
        pass
         
        print(globals()) #显示全局变量中定义的名称空间的名字
        print(locals()) #在全局中是看全局,在局部中是看局部
         
        print(globals() is locals() )
        #True              #说明此时在全局名称空间

    1.1    内置名称空间

    (随着python解释器的启动而产生)
    
        print(sum)
        #<built-in function sum>    #内置函数
         
        import builtins            #查看内置参数的模块
        for i in dir(builtins): #查看有哪些内置函数
        print(i)

    1.2.    全局名称空间

    在全局变量中定义的名称空间
        #文件执行会产生全局名称空间,指定是文件级别定义的名字都会放入改空间
        #如下全是全局定义, 如下有小区别
         
        import time #模块级别定义
        name="guolm" #文件级别定义
        def func(): #函数级别定义
        print("hello man")
        print(func())
        class foo: #类级别定义
        pass

    2. 局部作用域:

     
        范围:    局部名称空间
        有效期:局局有效,在局部可用, 函数调用时有效,调用结束后失效
        查找顺序:         局部名称空间 -->全局名称空间-->内置名称空间
        x=1000
        def func(c):
        x=2
        print(locals())     #查看局部名称空间
        func(1)
        {'x': 2, 'c': 1}        #这是局部名称空间

    2.1.   局部名称空间

    在调用函数时,会产生局部名称空间,只在函数调用时有效,函数结束时失效
        def func():
        x=1            #局部名称空间
        def f1():
        pass
     

    递归 

    最大递归层次 999层
        def calc(n):    #整除到1
        print(n)
        if int(n/2) >0:
        calc(int(n/2))
        print(n)
        print(calc(10))
     
    递归 2分查找 (从N个有序数据中找到想要的值,注:无序不能查找)
        #data = [ 1,2,4,6,7,8,9,11,14,16,18,19,20,22,25,29]
        data = range(1,4200000000)
        def binary_search(find_str,data_set,count):
        mid = int(len(data_set)/2)
        if mid==0:#代表列表只剩下一个值了,没必要继续找了
        if data_set[mid] == find_str:
        print("find it finally",find_str,count)
        else:
        print("cannot find this num in list",find_str,count)
        return
        if data_set[mid] == find_str:
        print("find it",find_str,mid)# find_str in left side
        elif data_set[mid] > find_str:
        print("going to search in left ",data_set[mid],data_set[0:mid])
        binary_search(find_str,data_set[0:mid],count+1)
        else:#find_str in right side
        print("going to search in right ",data_set[mid], data_set[mid+1:])
        binary_search(find_str, data_set[mid+1:],count+1)
        binary_search(13354245, data,0)
    1 内置函数
        1. type    判断类型
        2.     name =("a","b")
              print(type(name)) #看name类型 获取类
              #<class 'tuple'>
        3. bool(name)            0 空格,None都是False,其他都是True
        4.     name =("a","b")
              print(bool(name))
        5. len(name)               显示数据类型长度
        6. name =("a","b")
          print(len(name))
        7. abs()    #返回值为正数
        8.     print(abs(-1)) #返回1
              print(abs(2)) #返回2
              print(abs(-0.1)) #返回0.1
        9. all()    #判断为True或False
        10.     print(all([1,2,3,4,5])) #值为True
              print(all([1,0])) #值为False, 值包含0,None,空都为False,其他都为True
              print(all([])) #值为True, 注意这是特殊情况,
        11. 二,八,十,十六进制
        12.     >>>bin(10) 二进制
              '0b1010'
              >>> 10 十进制(默认)
              10
              >>> oct(10) 8进制
              '0o12'
              >>> hex(10) 16进制
              '0xa' a表示10 b表示11 以此类推
        13. callable    可调用对象
        14.     #不是函数就不可被调用返回False
              def func():
              pass
              print(callable(func)) #返回True
        15. chr和ord
        16.     ascii码是美国默认字符集编码
              print(chr(68)) #数字转换成ascii码 
              #D
              print(ord("D")) #ascii码转换数字
              #68
        17. dir 查看可用参数(权限) (有5种数据类型+set等)
        18.     b={"1":"2"}
              print(dir(b))
        19. divmod   用于分页功能
        20.     print(divmod(100,3)) #取整数+余数
              (33, 1)
        21. eval 把字符串里的命令或数据类型提取使用
        22.     #提取命令
              cmd='print("三哥威武")'
              eval(cmd)
              #三哥威武
               
              提取数据类型
          
              #定义列表
              keys_one=[
              {"backend":"www.wy.org"},
              ["server","1.1.1.3","1.1.1.3",{"weight","20"},{"maxconn","3000"}],
              ["server","1.1.1.4","1.1.1.4",{"weight","20"},{"maxconn","4000"}],
              ]
              #把列表写入练习文件,
              with open("练习","w",encoding="utf-8") as f:
              f.write(str(keys_one)) #转成字符串形式写入 #文件写入只能是字符串形式
              with open("练习","r",encoding="utf-8") as f:
              dic=f.read()
              print(type(dic)) #字符串形式,(因为写入是就是字符串形式)
              dic=eval(dic) #使用eval提取出字符串中的数据类型,
              print(type(dic)) #列表类型
              print(dic[1]) #可以查询列表内容
          
               
               
        23. frozenset    定义不可变集合
        24.     s=frozenset({1,2}) #s=({1,2}) 这是可变集合
              s.add(3)
              print(s) #会报错 因为s现在是不可变集合
        25. format    字符串格式化
        26.     s="name:{},age:{},height:{}".format("guolm",23,"183")
              print(s)
              #name:guolm,age:23,height:183

        27. hash   获取哈希,(2个字符串相同,哈希值相同)
        28. #效果:校验的内容相同 返回的值就一致 
          #以后会用hash模块,略过
           
          print(hash("aaaaa"))
          print(hash("aaaaa"))
          -3564166969462102491
          -3564166969462102491
           
        29. id   取内存地址
        30.     #身份运算符
              x=1
              y=x
              print(id(x),id(y))
              #1508750464 1508750464
              print(x is y) #s 是 y
              #True
        31. pow 求余数
        32.     print(pow(10,2,6))
              #4
              #取余数 相当于10的2平方 除以6 得到的余数是4
        33. reversed 取反转结果
        34.     a=["a",2,3,4]
              for i in reversed(a):
              print(i)
              #显示的值是反向输出
              b=["a",2,3,4]
              print(list(reversed(b)))
              #[4, 3, 2, 'a']    #list也是迭代器 所以值可以反转
        35. round 保留小数
        36.     one=round(3.14159,4) #最后4表示保留4位小数,第4位小数四舍五入计算
              print(one)
              #3.1416
              one=round(3.14159,3) #最后4表示保留4位小数,第4位小数四舍五入计算
              print(one)
              #3.142
          
              one=round(3.14159)    #不输入保留位数,默认保留整数
              print(one)
              #3
        37. zip #两个相同长度的字符串,元组,列表组合成字典
        38.     #2个不同类型也可以组合
              s=("hello")
              a=[1,2,3,4,5]
              z=zip(s,a)
              print(z)
              #<zip object at 0x0000004021D90608> z变成迭代器
              for i in z:
              print(i)
        39. __import__() #以字符串的形式导入模块
        40.     import time
              import time
              m=__import__("time")
              m.sleep(3) #沉睡2秒
              print("Gacvin Kwok is super man")
        41. sum 求和
        42.     a=sum([1,2,3,4]) #相当于1+2+3+4
              print(a)
              10
        43. bytearray 字符串改值(在原内存空间更改.不是删除后增加)
        44.     a="guolm 你好"
              print(ascii(a)) #ascii码
              a=a.encode() #改成utf-8格式
              b2=bytearray(a) #可直接修改字符串
              b2[0]=98 #这是g(字节)改成b(字节)
              print(b2)
              #'guolm u4f60u597d'
              #bytearray(b'buolm xe4xbdxa0xe5xa5xbd')
        45. map 运算
        46.     a= map(lambda x:x*x,range(10)) #类似三元运算 实现x=x*x 显示每次结果 运算值是0-10
              #a= map(lambda x:x+1,range(10)) #类似三元运算 实现x=x+1 显示每次结果 运算值是0-10
              for i in a:print(i)
        47. reduce 运算求加,减,乘,除
        48.     from functools import reduce
              a= reduce(lambda x,y:x+y,range(10))  
              #计算0-9的总和 +号可改为 * / - range中的值也可改
              print(a)
              #45
        49. memoryview    在原内存空间直接修改数据
    如下对比 memoryview比默认方式速度快的一个等级
    import time
    #默认方式 原内存空间垃圾回收,开辟新内存空间,
    for n in (200000,400000):
    data=b"x"*n
    start = time.time()
    b=data
    while b:
    b=b[1:]
    print("memoryview",n,time.time()-start)
    #memoryview 200000 1.3159432411193848 #表示1.3秒
    #memoryview 400000 5.632980585098267   #表示5.6秒
    print("========================================")
    #memoryview在原内存空间直接修改
    for n in (200000,400000):
    data=b"x"*n
    start = time.time()
    b=memoryview(data)
    while b:
    b=b[1:]
    print("memoryview",n,time.time()-start)
    #memoryview 200000 0.04102897644042969 表示0.04秒
    #memoryview 400000 0.08105683326721191 表示0.08秒

  • 相关阅读:
    Java数据库——CallableStatement接口
    Java数据库——处理大数据对象
    Java数据库——PreparedStatement接口
    Java数据库——ResultSet接口
    Java数据库——连接关闭、增删改查
    Ubuntu下的MySQL安装
    JDBC
    注释(Annotation)
    类的生命周期
    Java反射机制<2>
  • 原文地址:https://www.cnblogs.com/Gavinkwok/p/6917191.html
Copyright © 2011-2022 走看看