函数+装饰器+迭代器+生成器

闭包函数
闭包:定义在内网函数,包含对外部作用域而非全局作用域
范围:一个函数套用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 \u4f60\u597d‘
            #bytearray(b‘buolm \xe4\xbd\xa0\xe5\xa5\xbd‘)
      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秒
时间: 2024-10-06 01:23:55

函数+装饰器+迭代器+生成器的相关文章

函数嵌套 ,名称空间与作用域 ,闭包函数 ,装饰器 ,迭代器, 生成器 三元表达式,列表解析,生成器表达式 递归与二分法, 内置函数

函数嵌套名称空间与作用域闭包函数装饰器迭代器生成器三元表达式,列表解析,生成器表达式递归与二分法内置函数--------------------------------------------函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数def max(x,y): if x>y: return x else: return ydef max1(a,b,c,d): res=max(a,b) res2=max(res,c) res3=ma

&lt;04day&gt;_函数嵌套--闭包函数--装饰器--迭代器--生成器

一.函数的嵌套定义 1.python函数支持嵌套 def f1(): #f1函数的定义 def f2(): #f2函数的定义 print('from f2') def f3(): #f3函数的定义 print('from f3') f2() f1() 嵌套函数--运行结果说明: 1首先调用f1()结果,f1函数为空.担保函f2函数,f2函数有内容打印并且有调用,f2函数包含f3函数,但f3函数无调用. 运行结果: 列子:多个数据之间的大小比较. #!/usr/bin/python # -*- c

python_day04 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式

本节课重要知识点内容如下: 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式 1.函数嵌套 函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数 def bar(): print('from nbar')def foo(): print('from foo') bar()foo()def max2(x,y): if x > y: return x else: return ydef max4(a,

day4装饰器-迭代器&amp;&amp;生成器

一.装饰器 定义:本质是函数,(装饰其他函数)就是为其它函数添加附加功能 原则:1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 实现装饰器知识储备: 1.函数及“变量” 2.高阶函数 a.把一个函数名当做实参传给另一个函数(在不修改被装饰器函数源代码的情况下为其添加新功能) b.返回值中包含函数名 3.嵌套函数 高阶函数+嵌套函数 = 装饰器 延迟3秒 import time def test1(): time.sleep(3) print('in the test1')

Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

python第四天装饰器+迭代器+生成器

1.函数嵌套:在调用一个函数的过程中,调用了其他函数 def f1(): x=1 def f2(): print('from f2') f2() f1()  2.名称空间与作用域 a. 名称空间:存放名字与变量值绑定关系的地方 (1)内置名称空间:在python解释器启动时产生,存放一些python内置的名字 (2)全局名称空间:在执行文件时产生,存放文件级别定义的名字. (3)局部名称空间:在执行过程中,如果调用了该函数则会产生该函数的局部名称空间.在调用该函数的时候生效,调用结束时失效 加载

Day4 装饰器——迭代器——生成器

一 装饰器 1.1 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if def foo(): print('foo') def bar(): print('bar') dic={ 'foo':foo, 'bar':bar, } while True: choice=input('>>: ').strip() if choice in dic: dic[ch

day-5 装饰器 迭代器 生成器

1.装饰器 1.1 带参数的装饰器 参数可以用来决定是否执行某个装饰器的某一部分 def outer(flag): def timer(func): def inner(*args,**kwargs): if flag: print('''执行函数之前要做的''') re = func(*args,**kwargs) if flag: print('''执行函数之后要做的''') return re return inner return timer @outer(False) def func