1.装饰器
装饰器:为原函数去扩展新功能,用新函数去替换旧函数
作用:为不改变原代码的前提下,实现功能上的扩展
符号:@(语法糖)
# 1.装饰器的基本用法
def kuozhan(func):
def newfunc():
print("厕所前,蓬头垢面")
func()
print("厕所后,精神抖擞")
return newfunc
def func():
print("我是宋云杰")
func = kuozhan(func) # func = newfunc
func() # newfunc()
# 2.@符号的使用
print("<===============================>")
"""
@符号作用:
(1) 可以自动把@符号下面的函数当成参数传递给装饰器
(2) 把新函数返回,让新函数去替换旧函数,以实现功能上的扩展(基于原函数)
"""
def kuozhan(func):
def newfunc():
print("厕所前,牛头马面")
func()
print("厕所后,黑白无常")
return newfunc
@kuozhan
def func():
print("我是高雪峰")
func()
# 3.装饰器的嵌套
print("<===============================>")
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()
# 4.用装饰器扩展带有参数的原函数
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 => func("孙致和","鸟窝") <=> newfunc("孙致和","鸟窝")
# 5.用装饰器扩展带有参数和返回值的原函数
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)
# 6.用类装饰器来拓展原函数
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()
"""
# 7.带有参数的函数装饰器
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) # => (2) kuozhan(func2) => newfunc2 (2) 发动技能做替换 func2 = newfunc2
def func2(self):
print("来也冲冲,去也冲冲")
@outer(3) # => (3) kuozhan(func3) => "我是女性" (2) 发动技能做替换 func3 = "我是女性"
def func3(self):
print("尿道外面,说明你短")
obj = MyClass()
print("<================>")
obj.func1() # <=> newfunc1
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.func3 或者 MyClass.func3 都是"我是女性" 字符串.
obj.func3 => return "我是女性"
MyClass.func3 => return "我是女性"
"""
# 8.带有参数的类装饰器
"""
如果参数是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():
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)
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 = "亢龙有悔"
"""
2.面向对象当中的方法
普通方法:有参或者无参,如果是无参,只能用类来调用
绑定方法:(1)绑定到对象,自动传递对象参数(2)绑定到类,自动传递类参数
静态方法:无论是对象还是类,都可以调用此方法,而不会默认传递任何参数
class Cat():
name = "tom"
# 普通方法
def mai_meng():
print("小猫会卖萌")
# 绑定方法(对象)
def attack(self):
print("小猫会卅(sua)人")
# 绑定方法(类)
@classmethod
def youmi(cls):
print(cls)
print("可以放大招,伤害最高")
# 静态方法
@staticmethod
def jump(a,b,c,d,e):
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()
3.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,name):
self.name = name
# 获取方法
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 # 自动触发del_username方法
# 获取操作
print(obj.username)