装饰器: ''' 装饰器:在不改变原有代码的情况下,为该原函数扩展新功能 特征:返回新函数,替换旧函数 语法:@ (语法糖)

# ### 装饰器:
'''
装饰器:在不改变原有代码的情况下,为该原函数扩展新功能
特征:返回新函数,替换旧函数
语法:@ (语法糖)
'''

# (1) 装饰器原型:
def kuozhan(func):
	def newfunc():
		print("厕所前,屁滚尿流")
		func()
		print("厕所后,站不起来")
	return newfunc


def func():
	print("我是个屌丝")

# 手动的 把新函数 赋值给 旧函数
func = kuozhan(func) # res = newfunc
func() #newfunc()

# (2) 装饰器@
print("<=-===>")
def kuozhan(func):
	def newfunc():
		print("厕所前,风流倜傥")
		func()
		print("厕所后,面黄肌瘦")
	return newfunc

@kuozhan
def func():
	print("我是一个高富川")

'''
第一步: 先把下面的func当成参数传递给kuozhan
第二部:把返回的新函数重新赋值给func
* 谁跟在@ 这个装饰器的下面,就会自动把谁当成参数传递
func = kuozhan(func)
'''
func()

# (3) 互相嵌套的装饰器函数
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("我是一个白富美5")

func() # 3 1 5 2 4 

# (4) 带有参数的装饰器
"""
原函数在扩展之前是几个参数,那么扩展之后也相应有几个参数
"""
def kuozhan(func):
	def newfunc(who,where):
		print("厕所前,干净整洁")
		func(who,where)
		print("厕所后,臭气熏天")
	return newfunc

@kuozhan
def func(who,where):
	print('{}在{}解手'.format(who,where))

func("马军强","鸟窝")

# (5) 带有参数返回值的装饰器
'''通过装饰器改造之后,原函数返回什么,新函数返回什么'''
def kuozhan(func):
	def newfunc(*args,**kwargs):
		print("厕所前,萎靡不振")
		res = func(*args,**kwargs)  #"电影院","游泳池",jzn="15克",ys="15碗",hw="15斤",sc="15吨"
		print("厕所后,兽性大发")
		return res
		
		
	return newfunc
	
@kuozhan
def func(*args,**kwargs):
	print(args)
	for i in args:
		print("茅厕的地点在:",i)
	# print(kwargs)
	dic = {'jzn':"境泽年","ys":"易思","hw":"黄文","sc":"舒畅"}
	
	'''
	lst = []
	for k,v in kwargs.items():
		# 如果k在dic这个字典里,说明这个字典存在这个键,然后我就通过键取值
		if k in dic:			
			lst.append("{} 留下了黄金 {}".format(dic[k],v))	
	'''
	
	lst = ["{} 留下了黄金 {}".format(dic[k],v) for k,v in kwargs.items() if k in dic ]
	return lst

	
res = func("电影院","游泳池",jzn="15克",ys="15碗",hw="15斤",sc="15吨")
print("<112233>")
print(res)


"""
* 和 ** 的魔术用法(函数的调用处)
def func(a,b,c):
	print(a,b,c)
func(*[1,2,3])

def func(a=1,b=2,c=3,*,d=4):
	print(a,b,c)
func(**{"a":3,"b":4,"c":5,"d":6})#func(a=3,b=4,c=5,d=6)
"""

# (6) 用类装饰器修饰原函数
class MyClass():

	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

# 方法一
"""
@MyClass.kuozhan1
def func():
	print("厕所进行时... ... ")
func()
"""

# 方法二
@MyClass()   #@obj => obj(func)
def func():
	print("厕所进行时... ... ")

func()

'''
先把@符号右边的值算出来,在通过@符号把下面的函数当成参数进行传递
@MyClass()  就相当于 @obj
把func当成参数传递给obj => obj(func)
obj当成一个函数在进行调用,自动触发__call__魔术方法
return newfunc
func = newfunc
func()  就相当于 newfunc()
'''


# (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:
			return "今天天气好晴朗哦"
	return kuozhan
			

class MyClass():

	@outer(1)  
	def func1(self):
		print("向前一小步")
		
	@outer(2)
	def func2(self):
		print("文明一大步")
		
	@outer(3)
	def func3(self):
		print("来也冲冲,去也冲冲")

print("<===>")
obj = MyClass()
obj.func1()
print("<===>")
obj.func2()
print("<===>")
print(obj.func3)

'''
outer(1) => 返回 kuozhan 函数
@kuozhan
func1

@符号开始发挥作用
把func1当成参数进行传递,传给kuozhan中的func进行接收
根据num 这个值进行判断 , 返回newfunc1
obj.func1 = newfunc1
obj.func1() <===> newfunc1()


@outer(2) => 返回 kuozhan 函数
@kuozhan
func3
@符号开始发挥作用
把func3当成参数进行传递,传给kuozhan中的func进行接收
obj.func3 = "今天天气好晴朗哦"
print(该值) [因为函数名可以作为变量使用.]
'''

# (8) 带有参数的类装饰器
"""
如果传递的参数是1,我就为该类,添加成员属性和方法
如果传递的参数是2,我就把该类当中的run方法变成属性
"""
class Kuozhan():
	ad = "贵族茅厕,欢迎您来,欢迎您在来"
	def __init__(self,num):
		self.num = num

	def __call__(self,cls):
		if self.num == 1:
			return self.kuozhan1(cls) #newfunc 返回
			
		elif self.num == 2:
			return self.kuozhan2(cls)
	def money(self):
		print("贵族茅厕收费标准,每小时10元,包月1400")
			
	def kuozhan1(self,cls):
		def newfunc():
			# 添加成员属性
			cls.ad = Kuozhan.ad
			# 添加成员方法
			cls.money = Kuozhan.money
			return cls()
			
		return newfunc
		
	def kuozhan2(self,cls):
		def newfunc():
			# 先来判断run方法是否在cls当中
			if "run" in cls.__dict__:
				#调用一个类中得run方法拿到返回值"亢龙有悔"
				res = cls.run()
				#成员属性run 从方法变成属性,值替换了
				cls.run = res  # 把"亢龙有悔"进行替换赋值给run成员属性
			return cls()
		return newfunc
		

@Kuozhan(1)  #@obj => obj(MyClass)
class MyClass():
	def run():
		return "亢龙有悔"

obj = MyClass()
print(obj.ad)
obj.money()
"""
Kuozhan(1) => obj  自动触发init方法,存储num =>self.num = num
@obj
@符发挥作用把MyClass当成一个参数传递给obj => obj(MyClass)
触发__call__魔术方法,最后将newfunc进行返回
MyClass = newfunc  以前是类 现在是函数
obj = MyClass() <===>  newfunc()
obj = cls() # cls() 是一个对象 是以前MyClass 这个类的对象
"""

@Kuozhan(2)
class MyClass():
	def run():
		return "亢龙有悔"

obj = MyClass()
print(obj.run)

print("<==========================================================>")
# 外面全局的abc 与 函数内部局部的abc 两者不发生冲突,彼此独立
class abc():	
	a  =19
	
def func(cls):
	cls.b = 20
	return cls
	
	
obj2 = func(abc)
print(abc().a)
abc =  99988777
print(abc)


print(obj2.b)
print(obj2.a)

  

猜你喜欢

转载自www.cnblogs.com/huangjiangyong/p/10924344.html