叠加装饰器:

  叠加装饰器
    - 每一个新的功能都应该写一个新的装饰器
    - 否则会导致,代码冗余,结构不清晰,可扩展性差

  在同一个被装饰对象中,添加多个装饰器,并执行。
  @装饰1
  @装饰2
  @装饰3
  def 被装饰对象():
    pass

  注意: 装饰器在调用被装饰对象时才会执行添加的功能。

  - 叠加装饰器:
    - 装饰的顺序: 由下到上装饰
    - 执行的顺序: 由上往下

  注意: 无论inner中出现任何判断,最后都要返回“调用后的被装饰对象” func(*args, **kwargs)

def wrapper1(func):
def inner1(*args, **kwargs):
print('1---start')
# 被裝飾對象在調用時,如果還有其他裝飾器,會先執行其他裝飾器中的inner
# inner2
res = func(*args, **kwargs)
print('1---end')
return res
return inner1 def wrapper2(func):
def inner2(*args, **kwargs):
print('2---start')
res = func(*args, **kwargs)
print('2---end')
return res
return inner2 def wrapper3(func):
def inner3(*args, **kwargs):
print('3---start')
res = func(*args, **kwargs)
print('3---end')
return res
return inner3
'''
叠加裝飾器的裝飾順序與執行順序:
- 裝飾順序: 调用wrapper装饰器拿到返回值inner
由下往上裝飾 - 執行順序: 调用装饰过后的返回值inner
由上往下執行
''' @wrapper1 # index《---inner1 = wrapper1(inner2)
@wrapper2 # inner2 = wrapper2(inner3)
@wrapper3 # inner3 = wrapper3(index)
def index(): # 被裝飾對象 # inner1 ---》
print('from index...') # 正在装饰
index = wrapper3(index)
index = wrapper2(index)
index = wrapper1(index) '''
inner1()
inner2()
inner3()
index()
'''
index() # 此处执行 # inner1() --> inner2() ---> inner3()

有参装饰器

# 无参装饰器: 装饰在被装饰对象时,没有传参数的装饰器。
'''
# 以下是无参装饰器
@wrapper1 # inner1 = wrapper1(inner2)
@wrapper2 # inner2 = wrapper2(inner3)
@wrapper3
''' # 有参装饰器: 在某些时候,我们需要给用户的权限进行分类
'''
# 以下是有参装饰器
@wrapper1(参数1) # inner1 = wrapper1(inner2)
@wrapper2(参数2) # inner2 = wrapper2(inner3)
@wrapper3(参数3)
'''
def user_auth(user_role):  # 'SVIP'
def wrapper(func):
def inner(*args, **kwargs):
if user_role == 'SVIP':
# 添加超级用户的功能
res = func(*args, **kwargs)
return res
elif user_role == '普通用户':
print('普通用户')
# 添加普通用户的功能
res = func(*args, **kwargs)
return res return inner
return wrapper # 被装饰对象
user_auth('SVIP')
等价于下面两行代码
wrapper = user_auth('普通用户')
@wrapper # @user_auth('SVIP') # wrapper = user_auth('普通用户')
#@wrapper #<--- 返回结果(wrapper) <---- user_auth()
def index():
pass # wrapper = user_auth('普通用户') 等价于这两行
# index=wrapper(index) index()

wraps: (了解)
  是一个修复工具,修复的是被装饰对象的空间。不用显示外层装饰器注释
  from functools import wraps

from functools import wraps

def wrapper(func):

    @wraps(func)  # 修改名称空间: inner ---》 func   不写此处变为装饰器注释
def inner(*args, **kwargs):
'''
此处是装饰器的注释
:param func:
:return:
'''
res = func(*args, **kwargs)
return res
return inner # ---》 func @wrapper
def index():
'''
此处是index函数的注释
:return:
'''
pass print(index) # 函数对象 # 函数对象.__doc__: 查看函数内部的注释
print(index.__doc__) # inner.__doc__

迭代器

- 迭代器
  迭代的工具。

  迭代:
    迭代指的是重复迭代,每一次迭代都是基于上一次的结果而来的。

  迭代器:
    迭代器指的是迭代取值的工具,它可以迭代取值。

  - 如果想要知道python中迭代器是什么?必须先知道什么是可迭代对象?

  可迭代对象: 所有的序列类型: str, list, tuple, dict, set, f
    凡是内部有str.__iter__()方法的都是可迭代对象。

  - 获取迭代器:
    通过可迭代对象.__iter__(), 得到的返回值就是 “迭代器对象”。
    迭代器是迭代取值的工具,作用是迭代取值。

    - 如何迭代取值:
      迭代器对象.__next__() # “每一次执行”,都会从迭代器对象中取出一个值

  - 总结: 可迭代对象 VS 迭代器对象:
   - 获取可迭代对象: 定义序列类型(str, list, set, tuple, dict, f)
    - 特点:
      内置有__iter__()

  - 获取迭代器对象: 通过可迭代对象调用.__iter__()得到返回值
    - 特点:
      内置有__next__()

  - 迭代器对象的优点:
    - 优点:
      1.不依赖于索引迭代取值。
      2.节省内存空间。

    - 缺点:
      1.取指定某个值麻烦
      2.每次取值都要从第一个值开始,无法同过索引取值。

      3.不能通过len计算长度

# 以下都是可迭代对象
'''
str1 = 'hello tank!'
str1.__iter__()
list1 = [1, 2, 3] # list([1, 2, 3])
list1.__iter__()
set.__iter__()
dict.__iter__()
tuple.__iter__()
open('a.txt').__iter__()
'''
# list1是一个可迭代对象
list1 = ['tank', 'jason鸡哥', 'sean', '饼哥'] # 获取迭代器对象: iter_list1
iter_list1 = list1.__iter__() while True:
# 补充: try: 捕获异常
try:
print(iter_list1.__next__()) # 报错 # 立即触发此处代码 StopIteration
except StopIteration:
break
测试迭代文件
f = open('user.txt', 'r', encoding='utf-8')
iter_f = f.__iter__() while True:
try:
print(iter_f.__next__()) except StopIteration: break

for循环本质

for循环原理
  语法: for i in 可迭代对象:
  in: 可迭代对象 ----> 内部会自动调用.__iter__() ---> 迭代器对象

  for i in 可迭代对象:
  # 会自定帮你调用__next__
  print(i)
  # for循环内部也会有一个捕获异常机制,一旦遇到异常也会停止取值。

list1 = [1, 2, 3, 4]

for line in list1:  # list1是可迭代对象 ----> 内部会自动调用.__iter__() ---> 迭代器对象
# 迭代器对象.__next__()
print(line)

迭代器对象

- 迭代器本质上是一个可迭代对象

- 文件本质上既是迭代器对象,也是可迭代对象。

- 可迭代对象不一定是迭代器对象

iter_set1 = set1.__iter__()
iter_set1.__next__() # 确定: 迭代器对象也是一个可迭代对象
# 判断可迭代对象是否是迭代器对象
# print(iter_set1.__iter__() is iter_set1) # True # 唯独文件比较特殊: 因为文件从读取出来的时候就是一个迭代器对象
# f ---> 可迭代对象, 还是迭代器对象
# f = open('user.txt', 'r', encoding='utf-8')
# f.__next__()
#
# # # 确定: 文件既是可迭代对象,也是迭代器对象。
# # # iter_f ---> 迭代器对象
# iter_f = f.__iter__()
# iter_f.__next__()
'''
list1 = [1, 2, 3]
# 迭代器对象
iter_list = list1.__iter__() str1 = '123'
# 迭代器对象
iter_str1 = str1.__iter__() print(iter_list is iter_str1) # False
''' # 可迭代对象
list1 = [1, 2, 3, 4] # iter_list1 ---> 迭代器对象
iter_list1 = list1.__iter__()
print(iter_list1 is list1) # False
# 可迭代对象不一定是迭代器对象

python基础语法8 叠加装饰器,有参装饰器,wraps补充,迭代器的更多相关文章

  1. python基础语法及知识点总结

    本文转载于星过无痕的博客http://www.cnblogs.com/linxiangpeng/p/6403991.html 在此表达对原创作者的感激之情,多谢星过无痕的分享!谢谢! Python学习 ...

  2. Python 基础语法_Python脚本文件结构

    目录 目录 前言 软件环境 Python Script文件结构 导入模块的流程 Python的包package 最后 前言 Python基础语法这一章,主要记录了Python的文件结构.逻辑运算符.算 ...

  3. python之最强王者(2)——python基础语法

    背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...

  4. Python 基础语法(三)

    Python 基础语法(三) --------------------------------------------接 Python 基础语法(二)------------------------- ...

  5. Python 基础语法(四)

    Python 基础语法(四) --------------------------------------------接 Python 基础语法(三)------------------------- ...

  6. Python 基础语法(二)

    Python 基础语法(二) --------------------------------------------接 Python 基础语法(一) ------------------------ ...

  7. Python 基础语法

    Python 基础语法 Python语言与Perl,C和Java等语言有许多相似之处.但是,也存在一些差异. 第一个Python程序 E:\Python>python Python 3.3.5 ...

  8. 吾八哥学Python(四):了解Python基础语法(下)

    咱们接着上篇的语法学习,继续了解学习Python基础语法. 数据类型大体上把Python中的数据类型分为如下几类:Number(数字),String(字符串).List(列表).Dictionary( ...

  9. python学习第五讲,python基础语法之函数语法,与Import导入模块.

    目录 python学习第五讲,python基础语法之函数语法,与Import导入模块. 一丶函数简介 1.函数语法定义 2.函数的调用 3.函数的文档注释 4.函数的参数 5.函数的形参跟实参 6.函 ...

随机推荐

  1. 利用ffmpeg获取视频帧

    如果要对视频帧进行处理,可以先把视频帧读取出来. sh文件代码如下: #!/usr/bin/env sh VIDEO=/home/xxx/video/ FRAMES=/home/xxx/frame/ ...

  2. DB2 Error : SQLCODE=-802,SQLSTATE=22003 异常的原因

    使用DB2时,报错为 DB2 Error : SQLCODE=-802,SQLSTATE=22003 主要原因: 是我们sql语句使用某个字段*86400后结果非常大,导致无法返回结果:因为某个字段* ...

  3. 哈夫曼树的构建(C语言)

    哈夫曼树的构建(C语言) 算法思路: 主要包括两部分算法,一个是在数组中找到权值最小.且无父结点两个结点位置,因为只有无父结点才能继续组成树: ​ 另一个就是根据这两个结点来修改相关结点值. 结构定义 ...

  4. python学习之旅

    python学习分类 python基础    +- day01——python初始.变量.常量.注释.基础数据类型.输入.if day02——while.字符串格式化.运算符.编码初识 day03—— ...

  5. Go在windows下执行命令行指令

    需要在Go写的服务里面调用命令行或者批处理,并根据返回的结果做处理. 在网上搜索了一翻,验证成功,现记录如下: cmd := exec.Command("cmd") // cmd ...

  6. 数据库‘master’中拒绝CREATE DATABASE权限

    今天在创建数据库的时候,遇到了没有创建数据库权限的问题,后来百度了一下解决了该问题. 1.先用windows身份验证登录,在安全性下面的找到自己创建的登录名,双击,在弹出的对话框中为它赋予权限. 2. ...

  7. [個人紀錄] git 設定

    -- git history git config --global alias.history=log --graph --all --pretty=format:'%C(bold blue)%H% ...

  8. 18 java I/O 系统

    流的类继承结构 我们首先看看流的类继承结构,有助于理解下个标签的内容 InputStream OutputStream Reader Writer File类 File类技能表示一个特定文件的名称,又 ...

  9. C#控制IIS动态添加删除网站

    我的目的是在Winform程序里面,可以直接启动一个HTTP服务端,给下游客户连接使用. 查找相关技术,有两种方法: 1.使用C#动态添加网站应用到IIS中,借用IIS的管理能力来提供HTTP接口.本 ...

  10. webpack等bundler是如何工作的-简化版本

    webpack- why and how 首先不要被webpack做的复杂花哨的工作所迷惑,到底webpack是个啥?一句话,webpack是一个module bundler(模块打包器).多一句话, ...