5.2函数小高级

5.2.1 函数当参数

  • 1 函数也可以当返回值
def v(dar):
    v = dar()
def n ():
    print(444)
v(n)

# 实例2
def v():
    print(666)
def n():
    return v
m =n()
m()

# 实例3
def func():
    print(555)

def info():
    print(666)
    return func()
v = info()
print(v)
  • 练习

    # 实例1
    def v():
        print(666)
    def n():
        return v
    m =n()
    m()
    
    # 实例2
    def v():
        print(666)
    
    def n():
        print('alex')
        v()
    n()
    
    # 实例3
    name ='alex'
    def v():
    print(name)
    def v1():
        name = 'aicr'
        print(name)
        v()  # alex
    v1() # aicr
    
  • 函数其实也是一种数据类型,可以当变量存储

# 实例1
def fucn():
    print('alex')
list = [fucn,fucn,fucn()]  #  加()直接执行了

list[0]()
list[1]()

# 实例2
def fucn():
    print('alex')

dic = {'k1':fucn,'k2':fucn()}

dic['k1']()
  • 面试题
'''用函数实现:
    用户输入 f1  话费查询
            f2   余额查询
             f3   人工服务
             f4   宽带业务
    '''

# 方法1
usee = input('请输入业务 :')
if usee =='f1':
    print(话费查询)
elif usee =='f2':
    xxxxx
else:
    xxxxxx

# 方法二  函数
def v1():
    print('话费')
def v2():
    print('余额')
def v3():
    print('人工')
def v4():
    print('宽带')

dic = {'f1':v1,'f2':v2,'f3':v3,'f4':v4}

usee = input('请输入:')
dic[usee]()

5.2.2 闭包

  • 闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
  • 闭包 就是在内层函数调用外层函数的变量
# 实例1
def func():
    a = 2
    def info():
        print(a)  # 调用外层函数
     info()
 func()

# 实例 2
def get():
    name = 'alex'

    def info():
        print(name)
    return info # 返回info的内存id
v = get()
v() # 相当于调用info

# 实例 3

def get(arg):
    def func():
        return arg
    return func()

v = get(666)
print(v)
1 闭包的作用:
  • 1 保护变量,不受外部改变
作用 1  保护变量,不受外部改变

'''
a = 10
def func():
    global a
    a =2

def info():
    global a
    a = 3

先 func()  再  info()   a =3
先 info()  再   func()   a= 2

全局变量不稳定,受影响
'''

# 闭包
def func():
    a = 10
    def info():
        print(a)
    info()
# 这样保护了变量不受其他影响

作用 2 使变量常驻内存

def func():
    a = 10
    def info():
        print(a)
     return info
v = func()

v()
2 查看是不是闭包
def func():
    a = 10
    def info():
        print(a)

    info()
    print(info.__closure__)  # 不是闭包返回  None

func()
3 闭包应用
'''
    闭包 应用   简易版爬虫
'''
from urllib.request import urlopen

def func():
    get = urlopen('https://www.dytt8.net/').read()
    def info():
        print(get)
    return info
print('第一次,慢')
v = func()
v()

print('以后就在内存读出')
v()
v()  # 闭包常驻内存 , 直接内存读出

5.2.3 lambda 函数表达式

  • 三元运算

    print('ture') if v > 6 else print('flase')
  • lambda ( 匿名函数)

v = lambda x: x*3
print(v(3))
v = lambda x,y:x*y
print(v(4,6))

# 三元运算和lambda
n = lambda x:x if x<4 else x+1
print(n(14))
# 也可以当作参数
lst = [lambda x: x*3 ,lambda x: x*3,lambda x: x*3 ]
n = lst[0](3)
print(n)
print(lst[1](3))
  • map + lambda

    n = map(lambda x:x*5,[1,2,3,4])
    for line in n :
        print(line)

5.4 高级函数

  • map (多对一)

    # 实例1
    n = map(lambda x : x+2,[1,2,3,4])
    for i in n:
        print(i)
    
    # 实例2
    lst =[map(lambda x:x+1,[1,2,3]),map(lambda x:x+2,[1,2,3]),map(lambda x:x+3,[1,2,3])]
    print(lst)
    '''[<map object at 0x000002B3D40B17F0>, <map object at 0x000002B3D40B1940>, <map object at 0x000002B3D40B1C50>]'''
    
    #实例3
    lst =[map(lambda x:x+1,[1,2,3]),map(lambda x:x+2,[1,2,3]),map(lambda x:x+3,[1,2,3])]
    n = lst[0]
    for line in n :
        print(line)
    
    # 实例4
    
    lst =[map(lambda x:x+1,[1,2,3]),map(lambda x:x+2,[1,2,3]),map(lambda x:x+3,[1,2,3])]
    for i in lst:
        for line in  i:
            print(line)
  • filter 过滤掉不符合条件的数据

    # 实例1
    n = filter(lambda x :x>4,[1,22,33,4,5,])
    for line in n:
        print(line) # 22,33,5
    
    # 实例2
    n = filter(lambda x :x if x<4 else print('flase') ,[1,22,3,4,5,])
    for line in n:
        print(line)
    

5.5 推导式

  • 列表

    lst = [i for i in range(10)]
    
    lst1 = [1 for i in range(10)]
    
    lst2 = [ i for i in range(10) if i <6]
    # [迭代的变量 for i in 可迭代的对象 判断 ]
    
    lst3 =[ i if i < 5 else 777 for i in range(10)   ]
    print(lst5)
    # 加if 在for后 , 加 if ....else 在for前
    
    lst4 = [lambda : i for i in range(10)]
    '''
    v =[]
    for i in range(10):
        v.append(lambda :i)
    
    n = v[1]()
    print(n)'''
    
    lst5 = [ lambda x : x if x+i >10 for i in range(10)]
    
    def func():
        pass
    lst6 = [func for i in range(10)]
    
    # 面试题
    def func():
        return [lambda x : x+i for i in range(10)]
    lst7 = [ i  for i in func() ]
    print(lst7[1](7))
    
    

    上面这个题。 不要死磕。 能明白多少就明白多少。 这个题对小白很不友好

  • 元祖(集合)

    # 元祖和集合都要循坏打印
    set1 =(i for i  in range(18 ))
    for i in set1:
        print(i)
    
    set1 ={lambda  : i for i  in range(18 )}
    for i in set1:
        print(i())
    
    def func():
        print(222)
    set3 = (func for i in range(10))
    for i in set3:
        i()
  • 字典

dic ={ 'k%d'%i:i for i in range(10)}
print(dic)
#同列表

5.6 递归

  • 函数内部调用自己 (不建议,占内存)
  • python 为了不爆内存 ,限制了递归次数1000次
# 实例1
def func(a):
    print(a)
    a = a +1
    func(a)
func(1)

# 实例2
def func(a):
    print(a)
    if a < 5:
        func( a + 1)

func(1)  # 1,2,3,4,5

# 实例3
def func(a):
    if a < 5:
        func( a + 1)
    print(a)

func(1)  # 5,4,3,2,1
'''
函数在每进入下一层的时候,当前层的函数并未结束,它必须等它调用的下一层函数执行结束返回后才能继续往下走。 所以最下面的那句print(n)会等最里层的函数执行时才会执行,然后不断往外退层,所以会出现 5,4,3,2,1的效果
'''

# 实例 4 

def func(a):
    if a ==5:
        return a
    info = func(a + 1) + 10
    return info
v = func(1)
print(v)  # 34

5.7 装饰器

1. 什么是装饰器
  • 装饰器就是在不改变原函数的情况下,调用函数前后增加代码

    def func(arg):
        def info():
            print('aaaaaaaaaaaaaaaaaaa')
            arg()
        return  info
    
    def v():
        xxxxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxxx
    
        print(1111111111111)
        return 3333
    
    data = func(v)
    data()
    
    def v1():
        xxxxxxxxxxxxxxxxxxx
        print('alex')
        xxxxxxxxxxxxxxxxxxx
    lst = func(v1)
    lst()
    
    '''
      如果在 函数v 和函数v1 加上百行代码, 你要一个一个加
      函数如果不只有 v v1 很多
        怎么办  -------------装饰器--------------
    '''
    
    # 实例1
    def func(arg):
        def info():
            print('alrx sb')  # 在调用函数前打印 alx sb
            arg()
            print('aaaaaaaaaaa')  #在调用函数后打印  aaaaaaaaa
    
        return  info
    
    def v():
        print(1111111111111)
    
    data = func(v)  # func的参数传入v函数  此时data = info 函数
    data()  # 执行data = 执行 info()
    
    # 实例2
    def func(arg):
        def info():
            print('aaaaaaaaaaaaa')
            v = arg()
            return v
        return  info
    
    def v():
        print(1111111111111)
        return 3333
    
    data = func(v)
    print(data())
    
2. 装饰器基本格式
'''
    上面的装饰器很low  因为  如果装饰上百个函数的话
    要重复  赋值操作
'''
def func(arg):
    def info():
        print('alex sb')
        arg()
        print('aaaaaaaaaa')
    return info

@func
 #  @func 简化 func函数的赋值
 #  @ 函数  第一步,调用func 把下面的函数名当做func函数的参数   # arg = v
 #      第二步 , func 的return info,赋值给下面函数  v = info
 # 但是 func中 arg还是指向 v函数id   而 v 重新的赋值
def v():
    print(666)

v()
3.关于参数装饰
# 实例1
'''
如果装饰的函数需要传参数
'''
def func(arg):
    def info(a):
        arg(a)
    return info
@func
def data(n):
    print(n)
data()
# 第一步 执行func(data)
# data = info函数
#执行data(参数)

########如果被装饰的函数n个参数,需要改装饰器

# 优化

def func(arg):
    def info(*args,**kwargs):
        arg(*args,**kwargs) # 加上*args **keargs 不用管被装饰的函数需要几个参数都能传
    return info

@func
def data(n1,n2,n3):
    print(n1,n2,n3)

data(1,2,n3=3)

@func
def inner(a1,a2,a3,a4):
    print(a1,a2,a3,a4)
inner('alex',1,2,3)  # alex 1 2 3
  • 装饰器标准格式

    def func(arg):
        def info(*args,**kwargs):
            data = arg()
            return data
        return info
    @func
4.关于返回值
# 实例1 

def func(arg):
    def info(*args,**kwargs):
        data = arg(*args,**kwargs)
        return data
    return info

@func
def inner():
    print('alex')
v = inner()
print(v)  # none

# 实例2

def func(arg):
    def info(*args,**kwargs):
        data = arg(*args,**kwargs)
        return data
    return info

@func
def inner():
    print('alex')
    return 666
v = inner()
print(v)  # 666
# 练习题

# 1 判断文件是否存在
'''
imprt os
os.path.exists()
True or flase
'''
import os
def func(arg):
    def info(*args,**kwargs):
        # 检查文件的路径是否存在

        lst= args[0]
        if not os.path.exists(lst):
            print('路径不存在')
            return None

        data = arg(*args,**kwargs)
        return data
    return info

@func
def inner(path):
    f1 = open(path,mode='r',encoding='utf-8')
    v = f1.read()
    print(v)
    f1.close()
    return True
v = inner("E:\代码库\电影下载地址.txt")
print(v)

5. 带参数的装饰器
# 实例1 

def inner(a):   # 在闭包外再嵌套一层,即带参数的装饰器
    print(a)
    def func(arg):
        def info(*args,**kwargs):
            data = arg(*args,**kwargs)
            return data
        return info
    return func

@inner('alex')
# 执行 inner
# inner 返回的值func   @func
# 执行ear = func(ear) = info
# 执行info函数
def ear(v):
    print(v)

n = ear(111)
print(n)

# 实例2

def inner(a):
    print(a)
    def func(arg):
        def info(*args,**kwargs):
            data = arg(*args,**kwargs)
            return data
        return info
    return func

@inner('alex')
def ear(v):
    print(v)
    return 666

n = ear(111)
print(n)

带参数的装饰器的执行过程其实是这样的。 先inner(xxx) 然后inner函数返回值再和前面的@组合成装饰器

第五章 函数day2的更多相关文章

  1. C++第五章函数

    书上的点: 这次直接写写画画了,遇到的bug也就直接敲了,忘记记录了,好在都在书上,所以勾画一下,提一下.发现每一章后面的小结,都蛮有意思的.可以抄一遍. 1.返回值的函数成为返回值函数(value- ...

  2. 第十五章 函数————函数的递归、生成器send 、匿名函数

    1.生成器send方法 send的工作原理 1.send发生信息给当前停止的yield 2.再去调用__next__()方法,生成器接着往下指向,返回下一个yield值并停止 例: persons=[ ...

  3. javascript第五章--函数表达式

    ① 递归 ② 闭包 ③ 模仿块级作用域 ④ 私有变量

  4. 15第十五章UDF用户自定义函数(转载)

    15第十五章UDF用户自定义函数 待补上 原文链接 本文由豆约翰博客备份专家远程一键发布

  5. python 教程 第五章、 函数

    第五章. 函数 定义语句后面要加冒号 1)    定义函数 def sayHello(): print 'Hello World!' sayHello() 2)    变量作用域 LEGB原则 L本地 ...

  6. 《python for data analysis》第五章,pandas的基本使用

    <利用python进行数据分析>一书的第五章源码与读书笔记 直接上代码 # -*- coding:utf-8 -*-# <python for data analysis>第五 ...

  7. 读《编写可维护的JavaScript》第五章总结

    第五章 UI层的松耦合 5.1 什么是松耦合 在Web开发中,用户界面是由三个彼此隔离又相互作用的层定义的: HTML是用来定义页面的数据和语义 CSS用来给页面添加样式 JavaScript用来给页 ...

  8. 《Linux内核设计与实现》课本第五章学习笔记——20135203齐岳

    <Linux内核设计与实现>课本第五章学习笔记 By20135203齐岳 与内核通信 用户空间进程和硬件设备之间通过系统调用来交互,其主要作用有三个. 为用户空间提供了硬件的抽象接口. 保 ...

  9. python学习心得第五章

    python学习心得第五章 1.冒泡排序: 冒泡是一种基础的算法,通过这算法可以将一堆值进行有效的排列,可以是从大到小,可以从小到大,条件是任意给出的. 冒泡的原理: 将需要比较的数(n个)有序的两个 ...

随机推荐

  1. tomcat用做图片服务器

    最近做了个小网站,就是用tinyce富文本编辑器,https://www.511easy.com/ 保持字体排版和图片 发现博客园的图片,一天之后就无法显示 就想着自己做一个图片服务器,上传图片到指定 ...

  2. 一位 iOS 大牛的 BAT面试心得与经验总结,送给正在迷茫 的你!

    前言: 目前形势,参加到 iOS 队伍的人是越来越多,可以说是已经达到了供过于求的地步了. 今年,找过工作人可能会更深刻地体会到今年的就业形势不容乐观,之前实习的时候就想着写一篇面经,后来忙就给忘了, ...

  3. 【Java高级】(一)JVM

    5.2.1.在Java中如何判断对象已死? 引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能被使用的 ...

  4. C#命名规范(简述)

    命名空间,类,事件,接口,常量,属性,方法使用Pascal命名,即首字母大写  参数,变量(类字段)使用camel命名法,即首字母小写. Pascal 方式--所有单词第一个字母大写,其他字母小写.  ...

  5. 在windows中使用 nvm 实现node多版本管理

    所谓 NVM 就是 Node Version Manager 的缩写,即 node的版本管理工具,我们可以在电脑中安装多个不同版本的node,并借由 NVM 来实现自由切换,详情可点击查看 NVM 官 ...

  6. ALLOT流控设备SSG

    Allot AC 系列产品EOL的通知如下. 该产品于2021年3月31日EOL. 替代的产品系列为SG/SSG系列. Allot Secure Service Gateway(SSG)应用程序和用户 ...

  7. 基于tess4j的图片文字提取

    1.文件结构目录 2.具体实现 ①添加maven依赖 <dependency> <groupId>net.sourceforge.tess4j</groupId> ...

  8. 我是这样一步步理解--主题模型(Topic Model)、LDA

    1. LDA模型是什么 LDA可以分为以下5个步骤: 一个函数:gamma函数. 四个分布:二项分布.多项分布.beta分布.Dirichlet分布. 一个概念和一个理念:共轭先验和贝叶斯框架. 两个 ...

  9. 通过mark和reset方法重复利用InputStream

    InputStreammarkreset 在这篇博客中我们已经简单的知道可以通过缓存InputStream来重复利用一个InputStream,但是这种方式的缺点也是明显的,就是要缓存一整个Input ...

  10. .NET加水印/验证码的NuGet包

    .NET加水印/验证码的NuGet包 我的在前两篇文章(水印,验证码)中,我介绍了使用Direct2D给图片加水印/验证码,今天我将其进行了封装,发布了一个NuGet包Sdcb.Imaging: &l ...