赞
踩
"""
装饰器: 为原函数去扩展新功能,用新函数去替换旧函数
作用: 在不改变原代码的前提下,实现功能上的扩展
符号: @(语法糖)
"""
def kuozhan(func): def newfunc(): print("厕所前,蓬头垢面") func() print("厕所后,精神抖擞") return newfunc def func(): print("我是宋云杰") func = kuozhan(func) # func = newfunc func() # newfunc() """ 厕所前,蓬头垢面 我是宋云杰 厕所后,精神抖擞 """
@符号作用:
(1)可以自动把@符号下面的函数当成参数传递给装饰器
(2)把新函数返回,让新函数去替换旧函数,以实现功能上的扩展
def kuozhan(func):
def newfunc():
print("厕所前,牛头马面")
func()
print("厕所后,黑白无常")
return newfunc
@kuozhan
def func():
print("我是高雪峰")
func() # # 厕所前,牛头马面 我是高雪峰 厕所后,黑白无常
def kuozhan1(func): def newfunc(): print("厕所前,人模狗样1") func() print("厕所后,斯文败类2") return newfunc def kuozhan2(func): def newfunc(): print("厕所前,洗洗手3") func() print("厕所后,簌簌口4") return newfunc @kuozhan2 @kuozhan1 def func(): print("我是葛龙0") func() # 31024
print("===========") def kuozhan(func): def newfunc(who, where): print("厕所前,萎靡不振") func(who, where) print("厕所后,兽性大发") return newfunc @kuozhan def func(who, where): print("{}在{}解手".format(who, where)) func("孙致和","鸟窝") # func("孙致和","鸟窝") <=> newfunc("孙致和","鸟窝") """ 厕所前,萎靡不振 孙致和在鸟窝接手 厕所后,兽性大发 """
print("==========") def kuozhan(func): def newfunc(*args, **kwargs): print("厕所前,饥肠辘辘") res = func(*args, **kwargs) print("厕所后,酒足饭饱") return res return newfunc @kuozhan def func(*args, **kwargs): lst = [] dic = {"gaoxuefeng": "高雪峰", "sunzhihe": "孙致和", "gelong": "戈隆"} # 解手的地点遍历出来 for i in args: print("解手的地点:", i) for k, v in kwargs.items(): if k in dic: strvar = dic[k] + "留下了" + v + "黄金" lst.append(strvar) return lst lst = func("电影院", "水下", gaoxuefeng = "15g", sunzhihe = "15顿", gelong="15斤") print(lst) """ 厕所前,饥肠辘辘 解手的地点: 电影院 解手的地点: 水下 厕所后,酒足饭饱 ['高雪峰留下了15g黄金', '孙致和留下了15顿黄金', '戈隆留下了15斤黄金'] """
print("============") class Kuozhan(): def __call__(self, func): return self.kuozhan2(func) def kuozhan1(func): def newfunc(): print("厕所前,老实巴交") func() print("厕所后,咋咋乎乎") return newfunc def kuozhan2(self, func): def newfunc(): print("厕所前,唯唯诺诺") func() print("厕所后,重拳出击") return newfunc # 方法一 @Kuozhan.kuozhan1 def func(): print("厕所进行中....") # func() """ 厕所前,老实巴交 厕所进行中.... 厕所后,咋咋乎乎 """ # 方法二 @Kuozhan() # @obj => obj(func) 对象 把@下面的函数当作参数传递给装饰器 def func(): print("厕所进行中....") func() """ 厕所前,唯唯诺诺 厕所进行中.... 厕所后,重拳出击 """
""" 代码解析: print("========分割线1========") Kuozhan() # =>obj def func(): print("厕所进行中....") @符第一次发动技能: func 当成参数传递给obj => obj(func) 这种形式把对象当成函数使用 -> 直接触发__call__魔术方法 调用结束之后 @符第二次发动技能: 将返回的新函数 赋值给 旧函数,形成替换的效果 func = newfunc func() <=> newfunc() """ """ print("========分割线2========") <==相当于==> def func(): print("厕所进行中....") obj = Kuozhan() func = obj(func) func() """
def outer(num): def kuozhan(func): def newfunc1(self): print("厕所前,干净整齐") func(self) print("厕所后,一片狼藉") def newfunc2(self): print("厕所前,大腹便便") func(self) print("厕所后,满口雌黄") if num == 1: return newfunc1 elif num == 2: return newfunc2 elif num == 3: # 把func3方法变成属性 return "我是女性" return kuozhan class MyClass(): @outer(1) # => (1) kuozhan(func1) => newfunc1 (2)发动技能做替换 func1 = newfunc1 def func1(self): print("向前一小步,文明一大步") @outer(2) # => (1) kuozhan(func2) => newfunc2 (2)发动技能做替换 func2 = newfunc2 def func2(self): print("来也冲冲,去也冲冲") @outer(3) # => (1) kuozhan(func3) => "我是女性" (2)发动技能做替换 func3 = "我是女性" def func3(self): print("尿到外面,说明你短") obj = MyClass() print("=============") obj.func1() # <=> newfun1 """ 厕所前,干净整齐 向前一小步,文明一大步 厕所后,一片狼藉 """ print("=============") obj.func2() """ 厕所前,大腹便便 来也冲冲,去也冲冲 厕所后,满口雌黄 """ print("=============") # obj.func3() error print(obj.func3) # 我是女性 print(MyClass.func3) # 我是女性
""" 代码解析: 套上outer这层函数就是为了保留1 2 3 三个参数,可以在闭包函数中使用 调用outer 结束之后,才是返回正常的装饰器kuozhan 此刻,@符第一次发动技能, 把func1当成参数传递给kuozhan, 返回newfunc1 然后,@符第二次发动技能, 将返回的newfunc1替换原来func1 obj.func1() => newfunc1(obj) if num == 1 返回闭包函数newfunc1 if num == 2 返回闭包函数newfunc2 来做替换 obj.func3 在执行时,装饰器已经把func3变成了属性func3 = "我是女性" 所以obj.fun3 或者 MyClass.func3 都是"我是女性" 字符串 obj.func3 => return "我是女性" MyClass.func3 => return "我是女性" """
""" 如果参数是1,就为当前类添加成员属性和方法 如果参数是2,就把原方法run变成属性 """ class Kuozhan(): money = "贵族厕所,每小时1000元,贵族厕所欢迎您来,欢迎您再来" def __init__(self, num): self.num = num def __call__(self, cls): if self.num == 1: return self.newfunc1(cls) elif self.num == 2: return self.newfunc2(cls) def ad(self): print("贵族茅厕,茅厕中的百岁山") def newfunc1(self, cls): def newfunc(): # 为当前cls这个类,添加属性 cls.money = Kuozhan.money # 为当前cls这个类,添加方法 cls.ad = Kuozhan.ad return cls() return newfunc def newfunc2(self, cls): def newfunc(): # 判断run成员是否在类中 if "run" in cls.__dict__: # 调用类中的方法,得到对应的返回值 res = cls.run() # 把返回值重新赋值到run属性上 cls.run = res # cls.run = "亢龙有悔" return cls() return newfunc print("================") # 参数1 @Kuozhan(1) class MyClass(): def run(): return "亢龙有悔" obj = MyClass() print(obj.money) # 贵族厕所,每小时1000元,贵族厕所欢迎您来,欢迎您再来 obj.ad() # 贵族茅厕,茅厕中的百岁山
""" 参数为1,代码解析: @Kuozhan(1) => @obj => @符第一次发动技能 把MyClass当成参数传递给obj => obj(MyClass) => return self.newfunc1(cls) => return newfunc @obj => @符第二次发动技能 实现替换效果,将MyClass = newfunc obj = MyClass() = newfunc() = cls() = 对象 对象.属性 obj.money 对象.方法 obj.ad() """ """ 全局范围内类 class Ceshi(): ad = 10 obj = Ceshi() print(obj.ad) def func(cls): cls.money = 100 return cls() # 把类当成参数传递到函数当中,在局部空间中,形成独立的副本 obj = func(Ceshi) # 把类变量Ceshi 变成字符串 Ceshi = "你好" # 发现局部空间中类对象中的成员,并没有受到影响 print(obj.money) # 100 """
# 参数2
@Kuozhan(2)
class MyClass():
def run():
return "亢龙有悔"
obj = MyClass()
print(obj.run) # 亢龙有悔
"""
参数为2,代码解析:
@Kuozhan(2) => @obj => @符第一次发动技能:
把MyClass当成参数传递给obj => obj(MyClass) => return self.newfunc2(cls) => return newfunc
@obj => @符第二次发动技能
实现替换效果,将MyClass = newfunc
obj = MyClass() = newfunc() = cls() = 对象
对象.run = "亢龙有悔"
"""
"""
普通方法: 有参或者无参,如果是无参,只能类来调用
绑定方法: (1) 绑定到对象(字自动传递对象参数) (2) 绑定到类(自动传递类参数)
静态方法: 无论是对象还是类,都可以调用此方法,而不会默认传递任何参数
"""
class Cat(): name = "tom" # 普通方法 def mai_meng(): print("小猫会卖萌") # 绑定方法(对象) def attack(self): print("小猫会抓人") # 绑定方法(类) @classmethod def youmi(cls): print(cls) print("可以放大招,伤害最高") # 静态方法 @staticmethod def jump(): print("小猫会上树,抓老鼠")
obj = Cat() # 普通方法(无参方法只能类调用) Cat.mai_meng() # 小猫会卖萌 # obj.mai_meng() error # 绑定方法(对象) obj.attack() # 小猫会抓人 Cat.attack(obj) # 小猫会抓人 # 绑定方法(类) """对象和类都可以调用绑定到类的方法 推荐使用类来调用""" Cat.youmi() # 可以放大招,伤害最高 obj.youmi() # 可以放大招,伤害最高 # print(obj.__class__) # 静态方法 obj.jump() # 小猫会上树,抓老鼠 Cat.jump() # 小猫会上树,抓老鼠
"""
property 可以把方法变成属性使用
作用: 控制属性的获取,修改,删除等操作
变向的增加成员的安全性,可以通过自定义的逻辑进行控制
自动触发: 要求名字相同,同一个名字
获取@property
设置@属性名.setter
删除@属性名.deleter
"""
# 写法一 class MyClass(): def __init__(self, name): self.name = name @property def username(self): # return self.name pass # 不获取 @username.setter def username(self, val): # 在触发时:val = 朴飘乐 self就是本对象 # self.name = val pass # 不设置 @username.deleter def username(self): # print("删除方法被触发...") # del self.name pass # 不删 obj = MyClass("朴一生") # 获取属性 print(obj.username) # 设置属性 obj.username = "朴飘乐" # 获取属性 print(obj.username) # 删除属性 del obj.username # 获取属性 print(obj.username)
# 写法二 class MyClass(): def __init__(self, naem): self.name = naem # 获取方法 def get_username(self): return self.name # pass # 不获取 # 设置方法 def set_username(self, val): self.name = val # pass # 不获取 # 删除方法 def del_username(self): # del self.name pass # property(获取方法, 设置方法, 删除方法) username = property(get_username, set_username, del_username) obj = MyClass("朴仁猛") # 获取操作 print(obj.username) # 自动触发get_username方法 # 设置操作 obj.username = "pdd" # 自动触发set_username方法 # 获取操作 print(obj.username) # 删除操作 del obj.username # 自动触发el_username方法 # 获取操作 print(obj.username)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。