Python装饰器

1. 基础

装饰器:可以修改其他函数的功能的函数,可以使得代码更简洁

1.函数装饰函数
如果计算每个函数的运行时间,并不影响原函数,则可以使用到装饰器


def show_time(func):
    def inner():
        start = time.time()
        func()
        end = time.time()
        print(end-start)
    return inner
 
@show_time
def add():
    print("add...")
 
@show_time   
def reduce():
    print("reduce...")
 
add()

2.函数装饰带参函数

def show_time(func):
    def inner(a,b):
        start = time.time()
        func(a,b)
        end = time.time()
        print(end-start)
    return inner
 
@show_time
def add(a,b):
    print("add...")
    print(a+b)
 
@show_time
def reduce(a,b):
    print("reduce...")
    print(a-b)
add(1,2)

3.装饰器带参数

 def Check(flag=True):
     def show_time(func):
         def inner(a,b):
             start = time.time()
             func(a,b)
             end = time.time()
             if flag==True:
                 print(end-start)
         return inner
     return show_time
 
 @Check()
 def add(a,b):
     print("add...")
     print(a+b)
 
 @Check(False)
 def reduce(a,b):
     print("reduce...")
     print(a-b)
 
 add(1, 2)
 reduce(1, 2)

4.保留原函数名字及描述

def show_time(func):
    @wraps(func)    #不改变原函数的名字和描述
    def inner(a,b):
        start = time.time()
        func(a,b)
        end = time.time()
        print(end-start)
    return inner
 
@show_time
def add(a,b):
    """
    test add
    """
    print("add...")
    print(a+b)
 
a = add(1, 2)
print(add.__name__)

5.函数装饰类

 def MyCheck(cls):
     def inner(a):
         print(cls.__name__)
         return cls(a)
     return inner
 
 @MyCheck  
 class Foo():
     def __init__(self,a):
         self.a = a
     def fun(self):
         print(self.a)
         
 a = Foo(1)
 a.fun()

6.类装饰函数

 class ShowTime():
     def __init__(self,func):
         self.func = func
     
     def __call__(self,a,b):
         print(self.func.__name__)
         return self.func(a,b)
 @ShowTime
 def add(a,b):
     print(a+b)
 
 add(1,2)

7.#类装饰类

class ShowTime(object):
    def __init__(self,cls):
        self.cls = cls
    
    def __call__(self,a):
        print(self.cls.__name__)
        return self.cls(a)
    
@ShowTime        
class accept(object):
    def __init__(self,a):
        self.v = a
    def fun(self):
        print(self.v)
        
a = accept("ceshi")
a.fun()

2. 应用

1.登录使用

LOGIN_USER = {"status":False}

def check(flag=True):
    def outer(func):
        def inner():
            if flag:
                if LOGIN_USER["status"]:
                    func()
                else:
                    print("*****please login*****")
                    u = input("please enter name:")
                    p = input("please enter password:")
                    if u=="frankshi" and p=="@123":
                        LOGIN_USER["status"] = True
                        LOGIN_USER["name"] = "franskhi"
                        func()
                    else:
                        print("*****please re-login*****")
                        inner()
            else:
                func()
                    
        return inner
    return outer

@check(False)
def home():
    print("home...")
    
@check()
def order():
    print("order...")
    
@check()
def shopping_car():
    print("shopping_car...")

def logout():
    if not LOGIN_USER["status"]:
        print("You didn't login.")
    else:
        LOGIN_USER["status"] = False

def run():
    while True:
        page_code = input("please enter page code:")
        if page_code=="0":
            home()
        elif page_code=="1":
            order()
        elif page_code=="2":
            shopping_car()
        elif page_code=="3":
            logout()
        elif page_code=="9999":
            break;
        else:
            pass
        
run()


3.附:装饰器@property

方法变属性

"""
java:
class Person{
    private name;//把name设为私有属性
    private age;//把age设为私有属性
    
    public String getName(){
              return name
    }
    public setName(String name){
             this.name=name
    }
    
    public  int getAge(){
             return age
   }
    
   public setAge(int age){
             this.age=age
   }

}

"""

class Person:
    def __init__(self,name, age):
        self.__name = name
        self.__age = age
        
    @property
    def name(self):
        return self.__name
    
    @name.setter
    def name(self,name):
        self.__name = name
    
    @name.deleter 
    def name(self):
        del self.__name
        
    @property
    def age(self):
        return self.__age
    
    @age.setter
    def age(self,age):
        self.__age = age
        
# p = Person("frankshi", 123)
# print(p.name)
# p.name = "shitou"
# del p.name
# print(p.name)

#同样可按如下方式实现:
class Person:
    def __init__(self,name, age):
        self.__name = name
        self.__age = age
    
    def get_name(self):
        return self.__name
    
    def set_name(self,name):
        self.__name = name
    
    def del_name(self):
        del self.__name
        
    def get_age(self):
        return self.__age
    
    def set_age(self,age):
        self.__age = age
        
    name = property(get_name,set_name,del_name, "这是name的一些方法")
    age = property(get_age,set_age,None, "这是age的一些方法")
    
    
p = Person("frankshi", 18)
print(p.name)       #frankshi
p.name = "shitou"
print(p.name)       #shitou
print(p.name.__doc__)
del p.age       #因为没有配置删除方法,所以报错:AttributeError: can't delete attribute


#简单应用:翻页
li = [i for i in range(50)]

class Page:
    def __init__(self, current_page):
        self.current_page = current_page
        self.count = 10
    
    @property
    def start(self):
        value = (self.current_page-1)*self.count
        if value<0:
            value = 0
        return value
    
    @property
    def end(self):
        value = self.current_page*self.count
        return value


while True:
    try:
        page_no = int(input("请输入您要查看的页码:"))
    except:
        page_no = int(input("请输入正确的页码格式:"))
    p = Page(page_no)
    print(li[p.start:p.end])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值