#装饰器:对类或者函数进行功能的扩展  很多需要缩进的没有进行缩进
'''
#第一步:基本函数
def laxi():
print('拉屎')
#调用函数
laxi()
laxi()

print('=======================================')
#第二步:扩展函数的功能(不能修改原函数)
#用于扩展基本函数的函数
#把一个函数(laxi函数)作为一个整体传给另外一个函数(kuozhan函数)
#这个函数(kuozhan函数)用形参func收到了laxi函数,收到之后在中间
#调用laxi函数,并且在前面后面扩展功能
def kuozhan(func):
#扩展功能1
print('拉屎之前')
#调用基本函数
func()
#扩展功能2
print('拉屎之后')
#这里需要有返回值才能传给laxi
#基本函数
def laxi():
print('拉屎')

#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
print(laxi)

#调用函数
#laxi()

print('=======================================')
#第三步:使用语法糖(就是语法)
#用于扩展基本函数的函数
def kuozhan(func):
#扩展功能1
print('拉屎之前')
#调用基本函数
func()
#扩展功能2
print('拉屎之后')
#这里需要有返回值才能传给laxi
#基本函数
@kuozhan#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
def laxi():
print('拉屎')
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
print(laxi)

#调用函数
#laxi()

print('=======================================')
#第四步:基本装饰器的实现
#用于扩展基本函数的函数
def kuozhan(func):
#内部函数(扩展之后的laxi函数)
def newlaxi():
#以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
#取名叫做newlaxi
#扩展功能1
print('拉屎之前')
#调用基本函数
func()
#扩展功能2
print('拉屎之后')
#这里需要有返回值才能传给laxi
#添加返回值
#return 12 laxi原来是函数,laxi扩展之后还以函数的形式赋值给laxi
#所以return后面必须是扩展之后的函数
return newlaxi
#基本函数
@kuozhan#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
def laxi():
print('拉屎')
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
print(laxi)#第四步的目的是为了让打印laxi函数的时候打印一个函数
#而不是像第二步和第三步打印回来的是None
#调用函数
laxi()#laxi就是扩展的内部函数newlaxi函数,就是return返回的值

print('=======================================')
#第五步:带有参数的装饰器
#用于扩展基本函数的函数
def kuozhan(func):
#内部函数(扩展之后的laxi函数)
#5由于调用的时候传了两个参数,未来的laxi函数没有参数接收
#5报错的时候显示newlaxi没有形参接收,但是给了两个实参
#5所以需要添加两个形参接收shui,na
def newlaxi(shui,na):#5调用的杨羊传到了shui,na
#4以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
#4取名叫做newlaxi
#扩展功能1
print('拉屎之前')
#调用基本函数
func(shui,na)#5上面的shui,na传到了这里的shui,na
#扩展功能2
print('拉屎之后')
#4这里需要有返回值才能传给laxi
#添加返回值
#4return 12 laxi原来是函数,laxi扩展之后还以函数的形式赋值给laxi
#4所以return后面必须是扩展之后的函数
return newlaxi
#基本函数
@kuozhan#laxi = kuozhan(laxi) #4laxi就相当于以前的result,用来接收返回值
def laxi(who,where):#5上面的func的shui,na传到了这里的who,where
print(who,'在',where,'拉屎')
print('拉屎')
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #4laxi就相当于以前的result,用来接收返回值
#print(laxi)#4第四步的目的是为了让打印laxi函数的时候打印一个函数
#4而不是像第二步和第三步打印回来的是None
#调用函数
laxi('杨俊','羊圈')#laxi就是扩展的内部函数newlaxi函数,就是return返回的值
laxi('燕飞','鸟窝')

print('=======================================')
def laxi():
print('拉屎')
return '擦屁股'
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
print(laxi)#第四步的目的是为了让打印laxi函数的时候打印一个函数
#而不是像第二步和第三步打印回来的是None
#调用函数
result = laxi()#laxi就是扩展的内部函数newlaxi函数,就是return返回的值
print(result)# 调用和返回值都打印出来了
print('=======================================')
#第五步:带有返回值的装饰器 把第四步复制过来
#用于扩展基本函数的函数
def kuozhan(func):
#内部函数(扩展之后的laxi函数)
def newlaxi():
#以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
#取名叫做newlaxi
#扩展功能1
print('拉屎之前')
#调用基本函数
result1 = func()
#扩展功能2
print('拉屎之后')

#未来的laxi函数没有返回值,所以在最后调用的时候返回值为None
#为newlaxi添加返回值
return result1

#这里需要有返回值才能传给laxi
#添加返回值
#return 12 laxi原来是函数,laxi扩展之后还以函数的形式赋值给laxi
#所以return后面必须是扩展之后的函数
#5装饰器用于返回未来的laxi函数的return
#5而不是newlaxi(laxi)自带的返回值
#5应该在newlaxi函数里面再加一个return
return newlaxi
#基本函数
@kuozhan#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
def laxi():
print('拉屎')
return '擦屁股'
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
#print(laxi)#第四步的目的是为了让打印laxi函数的时候打印一个函数
#而不是像第二步和第三步打印回来的是None
#调用函数
result = laxi()#laxi就是扩展的内部函数newlaxi函数,就是return返回的值
print('函数的返回值为',result)
print('=======================================')

#第六步:带有收集参数的函数的装饰器
#装饰器函数
def kuozhan(func):
#内部函数(扩展之后的laxi函数)
def newlaxi(*w,**n):
#以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
#取名叫做newlaxi
#扩展功能1
print('拉屎之前')
#调用基本函数
func(*w,**n)
#扩展功能2
print('拉屎之后')
return newlaxi
#基本函数
@kuozhan
def laxi(*who,**nums):
print('参与拉屎的有',who)
print('他们分别拉了多少屎',nums)
print('拉屎')

#调用函数,'
laxi('许钰','王成','秀峰','张波',xy = '15斤',wc = '15吨',xf = '15克',zb = '15升')

print('=======================================')

#第七步:带有参数的装饰器
#两个基本函数用同一个装饰器装饰
def outer(arg):
print(arg)
#这是装饰器的代码
def kuozhan(func):
#print(func) func接收的不再是laxi,而是la,chi
#未来的laxi函数
def newlaxi():
# 扩展功能1
print('拉屎之前')
# 调用基本函数
func()
# 扩展功能2
print('拉屎之后')

def newchifan():
# 扩展功能1
print('吃饭之前')
# 调用基本函数
func()
# 扩展功能2
print('吃饭之后')

if arg == 'la':
return newlaxi
elif arg == 'chi':
return newchifan

#返回装饰器
return kuozhan
#基本函数1
result = outer('la')
@result #@装饰器函数
def laxi():
print('拉屎')

#基本函数2
@outer('chi')
def chifan():
print('吃饭')

#调用基本函数
#laxi()
chifan()

print('==============================================')
#第八步:使用类作为装饰器参数
#装饰器使用的操作类
class Wish:
#祈求方法
def before():
print('拉屎之前')
#还愿方法
def after():
print('拉屎之后')
#装饰器函数
def outer(cls):
def kuozhan(func):
# 未来的laxi函数
def newlaxi():
# 扩展1(类中存在扩展内容)
cls.before()
# 调用基本函数
func()
# 扩展2(类中存在扩展内容)
cls.after()

return newlaxi

return kuozhan

#基本函数
@outer(Wish)#装饰器
def laxi():
print('拉屎')

#调用函数
laxi()

print('==============================================')
#第九步:使用类来作为装饰器

class kuozhan:

#接收装饰器的参数(函数outer)
def __init__(self,arg):
#print(self,arg)arg就是la
self.arg = arg

#制作一个内部函数(真正的装饰器 函数kuozhan)
def __call__(self,func):
#print(self,func)func就是laxi函数
#将func函数存入对象
self.func = func

return self.newlaxi
#在面向对象过程当中不提倡内使用内部函数,要提到前面
#定义称为一个成员方法
def newlaxi(self):
# 扩展功能1
print('拉屎之前')
# 调用基本函数
self.func()
# 扩展功能2
print('拉屎之后')

#基本函数
@kuozhan('la')# laxi = 对象(laxi)
def laxi():
print('拉屎')

#调用函数
laxi()

print('==============================================')
#第十步:装饰器来装饰一个类
def kuozhan(cls):
#print(cls)

#声明一个类并且返回
def newHuman():
# 扩展类的功能1
cls.cloth = '漂亮的小裙子'
# 扩展类的功能2
cls.hat = '亮丽的绿帽子'
#调用类(实例化对象)
obj = cls()
#返回实例化对象
return obj
return newHuman #要让返回的newHuman也能实例化对象
#类(被装饰的类)
@kuozhan #Human = kuozhan(Human) = newHuman
#最后调用的Human()= newHuman()= obj = cls()= 扩展后的Human()
class Human:
#属性
sex = '男'
age = 18

#方法
def liaomei(self):
print('妹子,这块砖头是你掉的吗')

#实例化对象
result = Human()
print(result)
print(result.__dict__)
print(result.cloth)
print(result.hat)
print('===================================================')
#函数的调用
def laxi():
print('拉屎')
return '撒尿'
result = laxi()
print(result)
'''
print('===================================================')
#第十一步:多层装饰器的嵌套

#装饰器1
def kuozhan1(func):
#定义装饰之后的函数
def newlaxi1():
# 扩展功能1
print('1-----拉屎之前')
# 调用基本函数
func()
# 扩展功能2
print('1-----拉屎之后')
return newlaxi1

#装饰器2
def kuozhan2(func):
#定义装饰之后的函数
def newlaxi2():
# 扩展功能1
print('2-----拉屎之前')
# 调用基本函数
func()
# 扩展功能2
print('2-----拉屎之后')
return newlaxi2

#基本函数
@kuozhan2
@kuozhan1
def laxi():
print('拉屎')

#调用函数
laxi()

python 装饰器 对类和函数的装饰的更多相关文章

  1. python 进阶篇 函数装饰器和类装饰器

    函数装饰器 简单装饰器 def my_decorator(func): def wrapper(): print('wrapper of decorator') func() return wrapp ...

  2. python 装饰器(五):装饰器实例(二)类装饰器(类装饰器装饰函数)

    回到装饰器上的概念上来,装饰器要求接受一个callable对象,并返回一个callable对象(不太严谨,详见后文). 那么用类来实现也是也可以的.我们可以让类的构造函数__init__()接受一个函 ...

  3. 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】

    一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...

  4. 详解Python闭包,装饰器及类装饰器

    在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...

  5. python装饰器学习详解-函数部分

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 最近阅读<流畅的python>看见其用函数写装饰器部分写的很好,想写一些自己的读书笔记. ...

  6. python 解除装饰器,调用原本函数。

    假设fun函数被装饰器装饰了,name调用fun,就不是调用fun本身了,那么如何继续调用本身呢.使用fun_raw = fun.__wrapped__这样使用fun_raw就是调用没被装饰器修饰后的 ...

  7. python函数知识七 闭包、装饰器一(入门)、装饰器二(进阶)

    21.闭包 闭包:在嵌套函数内,使用非全局变量(且不使用本层变量) 闭包的作用:1.保证数据的安全性(纯洁度).2.装饰器使用 .__closure__判断是否是闭包 def func(): a = ...

  8. Python学习之高阶函数--嵌套函数、函数装饰器、含参函数装饰器

    玩了一晚上王者,突然觉得该学习,然后大晚上的搞出来这道练习题,凌晨一点写博客(之所以这么晚就赶忙写是因为怕第二天看自己程序都忘了咋写的了),我太难了o(╥﹏╥)o 言归正传,练习题要求:构造类似京东的 ...

  9. Python--函数对象@命名空间与作用域@包函数@装饰器@迭代器@内置函数

    一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...

随机推荐

  1. 动态规划——稀疏表求解RMQ问题

    RMQ (Range Minimum/Maximum Query)问题,即区间最值查询问题,是求解序列中的某一段的最值的问题.如果只需要询问一次,那遍历枚举(复杂度O(n))就是最方便且高效的方法,但 ...

  2. 图例演示在Linux上快速安装软RAID的详细步骤

    物理环境:虚拟机centos6.4 配置:8G内存.2*2核cpu.3块虚拟硬盘(sda,sdb,sdc,sdb和sdc是完全一样的)        在实际生产环境中,系统硬盘与数据库和应用是分开的, ...

  3. Java笔试题-List l = new List()

    前言: 最近遇到的一道很基础的题,有时候大家可能离开了编译器就不行了. import java.util.List; /** * * @author catchegg * create date: 2 ...

  4. psfgettable - 从控制台字体中提取出嵌入的Unicode字符表

    总览 psfgettable 字体文件 [输出文件] 描述 psfgettable 命令从一个 .psf 格式的控制台字体中提取出嵌入的 Unicode字符表, 以易读格式输入到一个ASCII文件, ...

  5. 给定中序和后序遍历,求前序序列(C++递归方式实现)

    问题: 输入后序和中序,求中序遍历. 算法: void f2(string &pre,string in, string post) { ) //序列为空结束 return; ; //根节点 ...

  6. 第十五章 Kubernetes调度器

    一.简介 Scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上.听起来非常简单,但有很多要考虑的问题: ① 公平:如何保证每个节点都能被分配资源 ② ...

  7. shell分析nginx access log日志

    统计访问最多的ip1. tail -n 10000 xxaccess_log | cut -d " " -f 1 |sort|uniq -c|sort -rn|head -10 | ...

  8. Envoy的线程模型[翻译]

    Envoy threading Model 关于envoy 代码的底层文档相当稀少.为了解决这个问题我计划编写一系列文档来描述各个子系统的工作.由于是第一篇, 请让我知道你希望其他主题覆盖哪些内容. ...

  9. Spring MVC 跳转失败,但配置正确填坑

    1:正确写法 @RequestMapping("{type_key}.html") public String geren(Model model, @PathVariable S ...

  10. 返回结果的 HTTP 状态 码

    2xx 200:表示从客户端发来的请求在服务器端被正常处理了.   204:该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中 不含实体的主体部分.另外,也不允许返回任何实体的主体.   2 ...