#装饰器:对类或者函数进行功能的扩展  很多需要缩进的没有进行缩进
'''
#第一步:基本函数
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. 2019 Multi-University Training Contest 1 - 1011 - Function - 数论

    http://acm.hdu.edu.cn/showproblem.php?pid=6588 新学到了一个求n以内与m的gcd的和的快速求法.也就是下面的S1. ①求: $ \sum\limits_{ ...

  2. elementUI 导航栏点击之后改变背景色,背景色悬停

    一开始设置的是: .menuLeft .el-menu-item:hover{ background: #6db6ff !important; } .menuLeft .el-submenu__tit ...

  3. Mac版Navicat Premium激活教程

    工具: Navicat Premium12.0.20 安装包 下载注册机工具包 链接:https://pan.baidu.com/s/1NS8gk780ds1Xn-zHrSIzIw  密码:dvke ...

  4. Java虚拟机——Java内存区域与内存溢出

    内存区域 Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域.Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器.Java虚拟机栈.本地方法栈 ...

  5. Django--Forms组件使用

    Forms组件的使用 在html表单验证中,需要通过各种信息的验证,比如注册界面的姓名.密码.邮箱.电话等的验证,是否符合定义好的规则,不可能每次都要取出对应的字段一一判断,django内置了Form ...

  6. spring boot 提纲

    http://tengj.top/categories/Spring-Boot%E5%B9%B2%E8%B4%A7%E7%B3%BB%E5%88%97/ http://blog.csdn.net/ca ...

  7. vue 限制input[type=number]的输入位数策略整理

    https://blog.csdn.net/weistin/article/details/79664261 vue type="number   设置maxlength 是无效的 我们可以 ...

  8. BZOJ3331 BZOJ2013 压力

    考前挣扎 圆方树这么早就出现了嘛... 要求每个点必须被经过的次数 所以就是路径上的割点/端点++ 由于圆方树上所有非叶子圆点都是割点 所以就是树上差分就可以辣. 实现的时候出了一点小问题. 就是这里 ...

  9. docker:python与docker

    一:环境准备 pycharm:专业版(windows) docker ce 免费版(ubantu16.04) os: os:防火墙 二:开发流程 pycharm中开发环境搭建的工作原理: 1. pyc ...

  10. 转:C++ 11 Lambda表达式

    转:https://www.cnblogs.com/DswCnblog/p/5629165.html C++11的一大亮点就是引入了Lambda表达式.利用Lambda表达式,可以方便的定义和创建匿名 ...