闭包函数

闭包函数

函数我们知道是什么了,那么什么是闭包函数呢?

 我们从字面的意思就是包起来的函数,那么实际上的呢?

闭:定义再函数内部的函数

包:就是内部函数引用了外部函数作用域的的名字

总体就是函数内部的函数引用了外部函数作用域的名字,只要满足这两点就是闭包函数

示例:

sh = 123
def outer():
    y = 234
    def inner():   #函数inner是在函数outer里面的函数,已经满足函数内部的函数这一项
        print(sh,y) # 内部函数引用外部函数 y的作用域名字也满足了一项,sh是全局空间空的但是 y 已经满足了
    return inner 
res = outer()
print(res())
该示例重点强调只要满足两点就是闭包函数

需要注意的是名字查找顺序:函数定义阶段名字的查找顺序就已经固定死了,是不会因为函数调用位置的变化而从而变化的.

就好比汽车在出厂后已经把上车到启动的顺序已经设定好了,不会因为开车的人不同而改变上车的顺序,你总不能没有上车就让车自己去目的地把(目前的可以科技应该还不能够吧)

给函数传参的两种方式:

1.就是直接传参(默认值参数,位置参数,和可变长参数)

def uname(name):
    print('uname)
uname('钢铁侠')

 2.就是闭包传参

def outter(name):
    def index():
        print('name)
    return index
outter('黑寡妇')

小爬虫

爬虫的本质就是抓取网页的html代码

从代码里面获取想要得到信息的链接(url链接地址)

然后在顺着这个链接将所有的页面资源全部爬取下来

装饰器

装饰器就是闭包函数的一个应用的分支或者说升级或者一种方法

那么装饰器就是一个特定功能的工具,可以给需要装饰的对象添加新的功能

装饰器的原则:

  开放封闭原则:

    开放:开放就是对扩展的开放

    封闭:就是对修改的封闭

  装饰器对可调用的对象必须遵循两个原则:

    1.不可改变被装饰对象的源代码

    2.不可改变调用对象的调用方法,

  注:意思就是,他是大爷,他既然想舒服,但是他又不可以动

用法示例:

"""
统计函数lala的运行时间


"""
import time

def outter(fnuc): #func = 最原始的lala函数内存地址
def get_time(*args,**kwargs):  
start = time.time()
res = fnuc(*args,**kwargs) # func()就可以直接调用lala函数
end = time.time()
print('lala 运行时间:%s'%(start-end))
return res # func()的返回值
return get_time
#lala = outter(lala) #outter的最原始的lala函数的内存地址 lala就是outter的返回值get_time
#lala()

@outter # 等于 lala = outter(lala) lala('jason') 调用方式没有改变
def lala(name):
print('您点的28号技师,已接到通知五秒后到达您的房间')
time.sleep(5)
print('%s先生您好,我是28号技师的姐姐,保证服务到位'%(name))
lala('jason')
#也没有改变原来的代码,功能也扩展了计算lala函数的执行时间

 装饰器的语法糖:会将紧挨着他的可调用对象的名字当做参数自动传入调用otture

示例:

@outter # 等于 lala = outter(lala)  lala('jason') 调用方式没有改变  
def lala(name):
    print('您点的28号技师,已接到通知五秒后到达您的房间')
    time.sleep(5)
    print('%s先生您好,我是28号技师的姐姐,保证服务到位'%(name))
lala('jason')
#也没有改变原来的代码,功能也扩展了计算lala函数的执行时间

装饰器模板:

无参装饰器

def outter(func):
    def inner(*args,**kwargs):
        print('执行被装饰函数之前可以进行的操作')
        res = func(*args,**kwargs)
        print('执行完毕被装饰函数后的操作')
        return res
    return outter

 有参装饰器

def lalalala(data):
    def outter(func):
        def inner(*args,**kwargs):
            if data =='file':
                print('执行被装饰函数之前可以进行的操作')
                res = func(*args,**kwargs)
                print('执行被修饰代码之后可以进行操作的')
              return res # func()的函数返回值
          return inner #outter()的函数返回值
      return outter  #lalalala()的函数返回值

 函数的递归

函数在调用阶段直接或者间接的调用自身函数

递归分两个阶段:

  1.回溯:就是一次次重复的过程,这个重复的过程必须建立在每一次重复问题的复杂度都应该下降,也就是一层层的扒开

  2,递推:一次次往回推导的过程,也就是追溯.从结果一步步推到回去.

  递归函数不要考虑循环的次数 只需要把握结束的条件即可

"""
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18

import sys
print(sys.getrecursionlimit()) # 查看python中的递归深度


age(n) = age(n-1) + 2  # n > 1
age(1) = 18  # n = 1
"""
def age(n):         # 创建一个函数
    if n == 1:         #判断是否等于1,显然n != 1 但是n 等于1的返回值是18
        return 18       # n 等于1 是返回值等于18
    return age(n-1) + 2 #   n= 2 时 18+2 返回值是20 当n=3 返回值22 当n=4 返回值22+2 当输入n= 5时 返回值 24+2  依次类推
res = age(3)    # 遇见age() 首先执行age函数 age函数等于6
# 当等于指定的实参运行结束然后把返回结果给了res 那么输出res就得到了age(n)结果

  示例二:

"""
l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,]]]]]]]]]]]]]
将列表中的数字依次打印出来

"""


def lolo(l):
    for i in l:
        if type(i) is int:   # 如果i是整数就打印出来
            print(i)
        else:
            lolo(i)  # 如果不是整数,就是列表那么就把列表再for循环 吧里面的整数拿出来直到没有数据可以进行循环
lolo(l)
 

初识算法

 算法是什么:算法就是解决问题的高效率的方法

二分法:

在之前如需要在一纯数字的列表里面需要找到列表中的一个数字,那么我们只能一个一个的循环查找,这样的效率太慢了,如果是五六个还好,如果是成千上万条呢,那不是要找到猴年马月了,所以有人就写出了更快查找的方法就是二分法,二分法是拿需要查找的这个数字对列表中间的一个数字作比较,这样就行分段查找,提高了查找的速度.

运行条件:容器类型里面的数字必须是有大小顺序,因为需要作比较.

演示示例:

l = [1,3,4,5,7,9,64,,78,89,90,92,94,98,11,444,5555]

target_na = 92
def get_num(l,target_na):
    if not l:
        print('怕是找不到了')
        return
    print(l)
    midle_index = len(l) // 2 # 把中间那个参数索引取出来
    if target_na > l[midle_index]: # 判断要比对的数字是否小于中间的那个数字
        num_right = l[midle_indxe + 1:] #加1是因为顾头不顾尾
        get_num(num_right,target_na)
    elif target_na < l[midle_indxe]:
        num_left = l[0:midle_indxe]
        get_num(num_left, targer_num)
    else:
        print('find it ',target_na)
get_num(1,target_na)

 三元表达式:

  三元表达式就是if 的一个用法,它的使用场景推荐使用使用的只有两种,那就是对了怎么操作错了怎么操作

三元表达式固定表达式方法:

  

值 a if 条件  else 值b
       条件表达式成立则 值a
        表达式不成立则   值b

 

演示:

lald = input('请放假回家不(y/n)>>>:').strip()
lald = '回家' if lald == 'y' else '不回家'
print(lald)
  

 列表生成式:
平常我们要生成个列表需要循环,太麻烦了,而且效率低代码多,使用列表生成式只有一行代码

l = ['白龙马', '悟空', '沙悟净', '八戒', '三藏', '白骨精'] new_l = [] for name in l: new_l.append('%s都不是人'%name) print(new_l) 这两个例子的功能是相同的 l2 = ['白龙马', '悟空都', '沙悟净', '八戒', '牛魔王', '白骨'] res = ['%s都是妖怪'%name for name in l2] print(res)

  

字典生成器

for循环和使用枚举的方式快速的生产字典

l1 = ['jason','123','read']
d = {i:j for i,j in enumerate(l1) if j != '123'}
print(d)

 匿名函数

见名知意就是没有名字的函数,匿名函数的特点就是临时存在用完就没了,就是吃干抹净不认人了

func = lambda x,y:x+y
print(func(1,2))

:左边的相当于函数的形参
:右边的相当于函数的返回值
匿名函数通常不会单独使用,是配合内置函数一起使用

 

原文地址:https://www.cnblogs.com/ioipchina/p/11177973.html