闭包,装饰器

  1.函数名的运用,第一类对象

  2.闭包

  3.装饰器(初始)

1.函数名:可以向变量名一样,进行赋值操作.

def  func():

  print("呵呵")

a = func    #把函数当成一个变量赋值给另一个变量

a()             #函数的调用   func()

2.函数可以作为容器(list,tuple,dict)的元素,保存在容器内.

def func1():

  print("呵呵")

def func2():

  print("哈哈")

def func3():
  print("咯咯")

li = [func1,func2,func3]

for i in li:

  i()      #这样就实现了函数的调用,因为i是列表里的元素

3.函数名可以作为返回值返回

def func1():

  print("这里是函数")

  def func2():

    print("这里是函数2")

  return func2

fn = func1()   #执行函数1,函数1返回的是函数2,这时fn指向的就是上面函数2

fn()    #执行上面返回的函数.

4.函数名可以当做函数的参数

def func():

  print("吃了吗")

def func2(fn):

  print("我是func2")

  fn()    #执行传递过来的fn

  print("我是func2")

func2(func)  #把函数func当成参数传递给func2的参数fn

二.闭包

目的:是让内存永远的记住一个变量.

在内层函数中访问外层函数的局部变量叫闭包,这个时候外层(非全局)的这个局部变量将会常驻内存.

def func():

  name = "alex"

  def func2():

    print(name)    #闭包

  func2

func()

我们可以使用.__closure__返回cell就是闭包,返回None就不是闭包

def func():      #示例

  name = "alex"

  def func2():

    print(name)  #闭包

  func2()

  print(func2.__closure__)

func()

问题,如何在函数外边调用内部函数呢?

def outer():

  name = "alex"

  #内部函数

  def inner():
    print(name)

  return inner

fn = outer()  #访问外部函数,获取到内部函数的函数地址

如果是多层嵌套呢?很简单,只需要一层一层的往外层返回就行了

def func():

  def func1():

    def func2():

      print("呵呵")

    return func2

  return func1

func()()()

之后在爬虫项目用到的很多.一个例子.

from urllib.request import urlopen

def but()

  content = urlopen("网址").read()

  def get_content():

    return content

  reurn get_content

fn = but()  #这个时候就开始加载网址的内容

      #后面需要涌到这里面的内容就不需要在执行非常耗时的网络连接操作了

content = fn()  #获取内容

print(content)

content2 = fn()  #重新获取内容

print(content2)

综上,闭包的作用就是让一个变量能够长驻内存,供后面的程序使用

三.装饰器(初始)

开闭原则(开放封闭原则):对添加功能开放,对修改代码封闭.

我们来看一个例子:

def func():

  print("小树苗")

func()

如果我要给小树苗浇水怎么添加呢?

def func():

  print("浇水")    #直接添加,违反了开放封闭原则.

  print("小树苗")

func()

所以我们用另一种方式:

def func():

  print("小树苗")

def func1():

  print("浇水")         #这样更改了它的调用方式,还是违背了开放封闭原则.

  func()

func1()

为了要达到既不改变又要修改的这一目的,装饰器就诞生了;装饰器完美地实现了这个功能,在不改变原函数的情况下又实现了对原函数功能的扩展.

def func():

  print("小树苗")

def func1(fn):

  def inner():

    print("浇水")

    fn()

    print("施肥")

  return inner

func = func1(func)

func()        #这里的func()调用的是inner函数.

到此装饰器的模型就出来了,还有一些细节需要注意.

我们再用一个示例来注意细节:

def func(fn):

  def inner(g*args,**kwargs):

    print("兄弟,约妹好玩吗?")

    ret = fn(*args,**kwargs)

    print("逗我呢")

    return ret

  return inner

@func          == #nana = func(nana)

def nana(*args,**kwargs):

  print("约妹",*args)

  return "真吓人"

sou = nana("付芙蓉","凤姐","大妈")

print(sou)

这个就是完整的装饰器模型了.

def func(fn):

  def inner(*args,**kwargs):

    #装饰函数执行前的内容

    ret = fn(*args,**kwargs)

    #装饰函数执行后的内容

    return ret

  return inner

@func     == # nana = func(nana)

def  nana()

  函数体

nana()  #调用目标函数

个人声明:今天的知识很绕,请用心分析,仔细琢磨.

原文地址:https://www.cnblogs.com/fengkun125/p/9184889.html