day20-Python运维开发基础(装饰器 / 类中的方法 / 类的方法变属性)

 

1. 装饰器 / 类中的方法 / 类的方法变属性

 

 

# ### 装饰器
"""
定义:装饰器用于拓展原来函数功能的一种语法,返回新函数替换旧函数
优点:在不更改原函数代码的前提下 给函数拓展新的功能
语法:@
"""

# 1.装饰器的原型
def kuozhan(func):
    def newfunc():
        print("厕所前,蓬头垢面")
        func()
        print("厕所后,容光焕发")
    return newfunc

def func():
    print("我是高富帅")

func = kuozhan(func) # func = newfunc
func()   # newfunc()

# 2.装饰器@符语法
"""
@符有两个作用:
    (1)把@符下面的函数当成一个参数传递给装饰器
    (2)装饰器经过装饰之后,把新函数返回,让新函数去替换旧函数 (在不改变原有代码的前提下,扩展新功能)
"""

def kuozhan(func):
    def newfunc():
        print("厕所前,衣衫褴褛")
        func()
        print("厕所后,光鲜亮丽")
    return newfunc

@kuozhan
def func():
    print("我是白富美")

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()

print("<===============>")
# 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("黄乐锡","鸟窝")


print("<===============>")
# 5.用装饰器装饰带有参数返回值的函数
def kuozhan(func):
    # 在定义处 * 和 ** 用来收集,打包
    def newfunc(*args,**kwargs):
        print("厕所前,萎靡不振")
        # 在调用处 * 和 ** 用来打散,解包
        res = func(*args,**kwargs)
        print("厕所后,兽性大发")
        return res
        
    return newfunc

@kuozhan
def func(*args,**kwargs):
    dic = {"zyl":"邹永灵","zl":"张龙","zzl":"众赞林"}
    strvar = ""
    for i in args:
        strvar += i + " "
    print("解手地点:" + strvar)
    
    # "谁" 留下了"什么"
    """
    # 方法一
    lst = []
    for k,v in kwargs.items():
        if k in dic:
            res = dic[k] + "留下了" + v + "黄金"
            lst.append(res)
    """
    # 方法二    
    lst = [dic[k] + "留下了" + v + "黄金" for k,v in kwargs.items() if k in dic]
    return lst
    
res = func("电影院","水里",zyl="15克",zl="15斤",zzl="15吨",ww="没有")
print(res)

# 6.用类装饰器装饰原函数
class Kuozhan():
    # 原函数被func这个形参接收到了
    def __call__(self,func):
        # 调用一下kuozhan2函数 , 返回newfunc新函数
        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()

print("<=======>")
# 方法二
@Kuozhan() # @obj => obj(func) 把对象当成函数使用,触发__call__方法 
def func():
    print("厕所进行时 ... ")

# func = newfunc
func() # newfunc()


# 7.用带有参数的装饰器装饰原函数
"""为了保留参数n存储的值,在套一层函数形成闭包,延长n的生命周期,供内函数使用"""
def outer(n):    
    def kuozhan(func):
        def newfunc1(self):
            print("厕所前,饥肠辘辘1")
            func(self)
            print("厕所后,呕吐不止1")
            
        def newfunc2(self):
            print("厕所前,饥肠辘辘2")
            func(self)
            print("厕所后,呕吐不止2")
            
        if n == 1:
            return newfunc1
        elif n == 2:
            return newfunc2
        elif n == 3:
            return 5488
            
    return kuozhan
    
    
print("<========================>")
class MyClass():

    @outer(1) # @kuozhan
    def func1(self):
        print("向前一小步,文明一大步")
        
    @outer(2)
    def func2(self):
        print("来也冲冲,去也冲冲")
        
    @outer(3)
    def func3(self):
        print("绿巨人觉得还行")

obj = MyClass()
# 扩展原函数新功能
obj.func1() # newfunc1()
obj.func2() # newfunc2()
# 把方法变成属性
print(obj.func3) # func3 = 5488


# 8.用带有参数的类装饰器装饰原函数
"""
如果参数是1,就为当前这个类添加成员属性和方法
如果参数是2,就把当前这个类中的run方法变成属性
"""

class Kuozhan():
    ad = "贵族茅厕,欢迎您来,欢迎您再来"
    def __init__(self,num):
        self.num = num
        
    def money(self):
        print("贵族茅厕,每小时收费100,包月1450.")
        
    def __call__(self,cls):
        if self.num == 1:
            return self.kuozhan1(cls) 
        elif self.num == 2:
            return self.kuozhan2(cls)
    
    def kuozhan1(self,cls):
        def newfunc(): 
            self.addpty(cls)            
            # 返回的是对象
            return cls()
        
        return newfunc
        
    def addpty(self,cls):
        # 为当前cls添加成员属性
        cls.ad = Kuozhan.ad
        # 为当前cls添加成员方法
        cls.money = Kuozhan.money
    
    def kuozhan2(self,cls):
        def newfunc():
            return self.updatepty(cls) # cls()
        return newfunc        
        
    def updatepty(self,cls):
        if "run" in cls.__dict__:
            cls.run = cls.run() # "亢龙有悔"
            return cls()
"""
@obj => obj(MyClass) => newfunc @符发动第二次技能,将新函数替换旧函数 MyClass = newfunc
obj = MyClass() <=> newfunc() <=> cls()
obj.ad  obj.money()
obj.run = "亢龙有悔"
"""


# 功能一
@Kuozhan(1) # @obj => obj(MyClass) 把对象当成函数使用了,会触发__call__魔术方法
class MyClass():
    def run():
        return "亢龙有悔"

obj = MyClass()
print(obj.ad)
obj.money()

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

obj = MyClass()
print(obj.run)


# 扩展1
"""
# 把类当成一个参数传递到函数中,形成一个独立的副本;
class MyClass():
    a = 1
    
def func(cls):
    cls.ad = 2
    return cls()

obj = func(MyClass)
MyClass = 1
print(MyClass)
print(obj.ad)

# 可以在函数内部创建类,但是作用域只限定在函数的内部,外部不可见;
def func():
    class C():
        cbb = 10
    obj = C()
    return obj
obj = func()
print(obj.cbb)    
"""
装饰器 示例代码
# ### 类中的方法
"""
无参的普通方法 : 只能用类调用
绑定方法:
    (1)绑定到对象:在调用时,自动传递self对象参数
    (2)绑定到类  :在调用时,自动传递cls这个类参数
静态方法:
    无论是对象还是类都可以调用,把方法作为普通方法进行使用
"""

class Dog():
    def __init__(self,name):
        self.name = name
    
    # 无参普通方法
    def eat():
        print("小狗喜欢吃屎")
        
    # 绑定到对象的方法
    def tail(self):
        print(self.name)
        print("小狗看见主人,喜欢摇尾巴")
        
    # 绑定到类的方法
    @classmethod
    def jump(cls):
        print(cls)
        print("小狗喜欢接飞盘")
        
    # 静态方法
    @staticmethod
    def jiao():
        print("看见主人,就旺旺叫")

obj = Dog("迈克尔·旺旺")
# 无参普通方法
# obj.eat() error
Dog.eat()

# 绑定到对象的方法
# obj.tail()
# Dog.tail(obj) #不推荐

# 绑定到类的方法
# Dog.jump() # 推荐
# obj.jump()

# 静态方法 : 有几个参数就传递几个参数,跟普通方法的调用一样;
# Dog.jiao()
obj.jiao()
类中的方法(绑定方法与静态方法) 示例代码
# ### property
"""
把方法变成属性:用来控制成员的 获取 , 设置 , 删除
@property       获取
@方法名.setter  设置property
@方法名.deleter 删除
"""
# 写法一
class MyClass():
    
    def __init__(self,name):
        self.name = name
    # 获取
    @property
    def username(self):
        # return self.name
        pass

    # 设置
    @username.setter
    def username(self,val):
        # self.name = val
        pass
    
    # 删除
    @username.deleter
    def username(self):
        # del self.name
        pass
        
obj = MyClass("周永玲")
# 获取username 触发property修饰的方法
res = obj.username
print(res)

# 设置username 触发username.setter修饰的方法
obj.username = "王永玲"

print(obj.username)

# del obj.username 触发sername.deleter装饰器修饰的方法
del obj.username
print(obj.username)


# 写法二
class MyClass():
    def __init__(self,name):
        self.name = name
        
    # 获取属性
    def get_username(self):
        return self.name
    
    # 设置属性
    def set_username(self,val):
        self.name = val

    # 删除属性
    def del_username(self):
        # del self.name
        pass
    
    # 必须按照这个顺序进行传递:获取方法 , 设置方法 , 删除方法
    username = property(get_username,set_username,del_username)

obj = MyClass("罗宗源")
# 获取属性 自动触发get_username方法
res = obj.username
print(res)
# 设置属性 自动触发set_username方法
obj.username = "黄乐锡"
print(obj.username)
# 删除属性 自动触发del_username方法
del obj.username
print(obj.username)
property_类的方法变属性 示例代码

 

 

 

 

 

 

day20

posted on 2020-01-10 20:54  tengq  阅读(221)  评论(0编辑  收藏  举报

导航