Python装饰器

一、闭包函数

简单来说闭包函数是传参的另外一种方式,将参数+函数包在一起返回出去。

1.两种为函数传参的方式

# 1.使用参数的形式
def func(x):
    print(x)

func(1)
func(1)

# 2.包给函数
def outter(x):
    
    def inner():
        print(x)
    return inner

f = outter(1)
f()
f()

2.闭包函数的应用

闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域。

应用领域:延迟计算(原来我们是传参,现在我们是包起来)、爬虫领域。

import requests

def outter(url):
    
    def inner():
    	response = requests.get(url)
    	print(f"done: {url}")
    return inner

baidu = outter('www.baidu.com')
python = outter('https://www.python.org')

baidu()
baidu()

python()
python()   

二、装饰器

装饰器本质就是一个函数a,装饰的对象也是一个函数b,用一个函数a去装饰一个函数b

装饰器的实现必须遵循两大原则:

  1. 不修改被装饰对象的源代码
  2. 不改变被装饰对象的调用方式
# 装饰器模板
def deco(func):
    
    def wrapper(*args, **kwargs):
        # 逻辑代码
        res = func(*args, **kwargs)
        return res
    return wrapper

# 装饰器具体使用
import time

def time_count(func):
    
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        end = time.time
        print(f'{func} run time is {end - start}')
        
        return res
    return wrapper

# 装饰器使用方式1
def index():
    print('index hahahahahahahahahahahhahaha')
    time.sleep(1)

index = time_count(index)
index()  # 此处index() = wrapper()


# 装饰器使用方式2
@time_count
def index():
    print('index hahahahahahahahahahahhahaha')
    time.sleep(1)
    
# 理解函数对象之后能更好的理解装饰器
# 这里的index即作为函数的参数传递给了time_count,又作为函数wrapper的返回值,返回给了index

三、迭代器

迭代器:更新换代,重复,基于上一次的结果推出下一次的结果

# 可迭代对象 (具有__iter__方法)

x = 1  # 不可迭代对象
s = 'nick'  # 可迭代对象
lt = [1, 2, 3]  # 可迭代对象
dic = {'a': 1, 'b': 2}  # 可迭代对象
tup = (1,)  # 元组只有一个元素必须得加逗号# 可迭代对象
se = {1, 2, 3}  # 可迭代对象
f = open('time.py')  # 可迭代对象
def func():  # 不可迭代对象
    pass

# 有__iter__()方法的对象就是可迭代对象,然后除了数字类型和函数都是可迭代对象
# 可迭代对象通过__next__()方法依次取值

# 迭代器对象:具有__iter__以及__next__方法的叫做迭代器对象

s = 'nick'  # 可迭代对象,不属于迭代器对象
lt = [1, 2, 3]  # 可迭代对象,不属于迭代器对象
dic = {'a': 1, 'b': 2}  # 可迭代对象,不属于迭代器对象
tup = (1,)  # 元组只有一个元素必须得加逗号# 可迭代对象,不属于迭代器对象
se = {1, 2, 3}  # 可迭代对象,不属于迭代器对象
f = open('time.py')  # 可迭代对象,迭代器对象

# 只有文件是迭代器对象

# for循环原理(迭代循环)
lt = [1, 2, 3]
lt_iter = lt.__iter__()
while True:
    try:
        print(lt_iter.__next__())
    except StopIteration:
        break
     
for i in lt:  # 可迭代对象;迭代器对象  不依赖索引取值,而是迭代取值.
    print(i)
  
# 1.首先使用iter把lt变成迭代器对象;对于文件也要使用iter方法把文件再一次iter下
# 2.然后使用next方法进行迭代取值
# 3.判断StopIteration异常,遇到异常终止

# 可迭代对象:具有__iter__方法的对象就是可迭代对象,除了数字类型和函数都是可迭代对象。
# 迭代器对象:具有__iter__和__next__方法的都是迭代器对象,只有文件时迭代器对象.

# 迭代器对象一定是可迭代对象;可迭代对象不一定是迭代器对象.
posted @ 2019-08-12 18:07  17vv  阅读(111)  评论(0编辑  收藏  举报