python decorator和@staticmethod()

@staticmethod()虽然定义在类里的函数,但是不受类的影响,就像定义在类外的函数一样。

class cal:
    cal_name = 'calculator'
    def __init__(self,x,y):
        self.x = x
        self.y = y
    
    def cal_add(self,x,y):
        return self.x + self.y

    @staticmethod       #静态方法 类或实例均可调用
    def cal_add2(x,y): 
        return x + y
    
    def cal_add3(self,x,y):
        return x + y
        
c1 = cal(10,11)      #实例化

print(cal.cal_name)
print(c1.cal_name)
print(c1.cal_add(7,8))
print(cal.cal_add2(6,7.5))
print(c1.cal_add2(6,7.5))
print(c1.cal_add3(7,8))

输出

calculator
calculator
21
13.5
13.5
15

所谓实例化就是c1=cal(10,11),类的constructor赋值。


在大多数应用中,decorator用于修饰函数,那么很显然,装饰器的参数就是函数。

举个例子,我们有100个foo,需要添加每个foo的运行时间。方法一,每个foo改写代码。

def foo1():
    print('hello foo1')
    start = time.time()
    time.sleep(3)
    end = time.time()
    print('spend %s s'%(end - start))

def foo2():
    print('hello foo2')
    start = time.time()
    time.sleep(3)
    end = time.time()
    print('spend %s s'%(end - start))

foo1()
foo2()

输出

hello foo1
spend 3.00324392319 s
hello foo2
spend 3.00317907333 s

方法二,写一个公用的函数调用100个foo,该函数参数即函数,即函数的函数。那么原来的foo代码就不用改写了。

def show_time(func):
    start_time=time.time()
    func()
    end_time=time.time()
    print('spend %s'%(end_time-start_time))
    
def foo():
    print('hello foo2')
    time.sleep(3)

show_time(foo)

输出

hello foo2
spend 3.00352692604

方法三,装饰器修饰100个foo,那么装饰器函数不但要是函数的函数,还必须是嵌套函数。


def show_time(func):
    def inner():
        start = time.time()
        func()
        end = time.time()
        print('spend %s'%(end - start))
    return inner

@show_time 
def foo():
    print('hello foo')
    time.sleep(1)
    
@show_time 
def foo2():
    print('hello foo2')
    time.sleep(2)

foo()
foo2()

输出

hello foo
spend 1.00129795074
hello foo2
spend 2.00224804878

装饰过的函数,如果执行函数()调用,那么编译执行时是执行内嵌的完整函数,否者会出现TypeError: 'NoneType' object is not callable。如果仅仅调用被装饰函数名(不带括号),那么装饰器函数不需要内嵌另一个函数。python的函数名是指针。

下面看一个编译先后顺序的例子。

def bread(func) :  
    def wrapper() :  
        print "</'''       '''\>"  
        func()  
        print "<\______/>"  
    return wrapper  
   
def ingredients(func) :  
    def wrapper() :  
        print "#tomatoes#"  
        func()  
        print "~salad~"  
    return wrapper  
@bread  
@ingredients   
def sandwich(food="--ham--") :  
    print food  
   
sandwich()

输出

</'''       '''\>
#tomatoes#
--ham--
~salad~
<\______/>

装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。


最后看看@property用法,一个事物的性质,比如一个半径等于r的圆是一个object,那么该圆的面积和周长和半径r是相关的,那么该圆的面积函数和周长函数最适合用@property修饰,构造该对象只需指定半径r。

import math
class Circle:
    def __init__(self,radius): 
        self.radius=radius

    @property
    def area(self):
        return math.pi * self.radius**2 
    @property
    def perimeter(self):
        return 2*math.pi*self.radius 

c=Circle(10)
print(c.radius)
print(c.area) 
print(c.perimeter) 

输出

10
314.159265359
62.8318530718

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞行codes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值