马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
转自:关于Python修饰符学习
注意:由于很多童鞋反馈原文一点都不好理解,小甲鱼负有连带责任……所以,我又重新把内容整理了一遍,增加了一些例子,希望能帮助到大家。
1. 修饰符的来源
借用一个博客上的一段叙述:修饰符是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。
修饰符是解决这类问题的绝佳设计,有了修饰符,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。
概括的讲,修饰符的作用就是为已经存在的对象添加额外的功能。
如下:
import time
def timeslong(func):
start = time.time()
print("It's time starting ! ")
func()
print("It's time ending ! ")
end = time.time()
return "It's used : %s." % (end - start)
def myfunc():
print("Hello FishC.")
t = timeslong(myfunc)
print(t)
实现结果:
It's time starting !
Hello FishC.
It's time ending !
It's used : 0.02497720718383789.
上面的程序中,定义了一个函数(timeslong()),对一个对象(代码中是 myfunc())的运行时间进行计算。
通常情况下,如果我们需要计算另外一个函数的运算时间,那么我们就需要修改 timeslong() 函数在调用时候的实参。
比如我需要统计 myfunc2 这个函数的运行时间,就需要调用 timeslong(myfunc2) 酱紫。
那么为了优化这种操作,Python 便提出了修饰符这个概念。
我们看下它是怎么实现的:
import time
def timeslong(func):
def call():
start = time.time()
print("It's time starting ! ")
func()
print("It's time ending ! ")
end = time.time()
return "It's used : %s." % (end - start)
return call
@timeslong
def myfunc():
print("Hello FishC.")
print(myfunc())
实现的结果是一样的:
It's time starting !
Hello FishC.
It's time ending !
It's used : 0.022337913513183594.
但是大家有没有发现,这一次我们不需要再去调用 timeslong() 函数了。
如果我有多个函数需要统计,那么使用起修饰符来就更优雅了:
import time
def timeslong(func):
def call():
start = time.time()
print("It's time starting ! ")
func()
print("It's time ending ! ")
end = time.time()
return "It's used : %s." % (end - start)
return call
@timeslong
def myfuna():
print("Hello World.")
@timeslong
def myfunb():
print("Hello Python.")
@timeslong
def myfunc():
print("Hello FishC.")
print(myfuna())
print("========================================")
print(myfunb())
print("========================================")
print(myfunc())
实现结果:
It's time starting !
Hello World.
It's time ending !
It's used : 0.023639202117919922.
========================================
It's time starting !
Hello Python.
It's time ending !
It's used : 0.01770305633544922.
========================================
It's time starting !
Hello FishC.
It's time ending !
It's used : 0.014674186706542969.
通过修饰符主要达到的目标是使得整个代码看起来更加美观,仅此而已。
另外,我们还可以进一步“优雅”,
那就是把它封装成类:
import time
class timeslong(object):
def __init__(self, func):
self.func = func
def __call__(self):
start = time.time()
print("It's time starting ! ")
self.func()
print("It's time ending ! ")
end = time.time()
return "It's used : %s." % (end - start)
@timeslong
def myfuna():
print("Hello World.")
@timeslong
def myfunb():
print("Hello Python.")
@timeslong
def myfunc():
print("Hello FishC.")
print(myfuna())
print("========================================")
print(myfunb())
print("========================================")
print(myfunc())
实现的结果是一样的:
It's time starting !
Hello World.
It's time ending !
It's used : 0.03470897674560547.
========================================
It's time starting !
Hello Python.
It's time ending !
It's used : 0.01266622543334961.
========================================
It's time starting !
Hello FishC.
It's time ending !
It's used : 0.014008522033691406.
其实呀,Python 也有内置的修饰符,它们分别是 staticmethod、classmethod 和 property,作用分别是把类中定义的实例方法变成静态方法、类方法和类属性。
简单地举个例子,如果我们将类这么写:
>>> class Hello(object):
... def print_hello(cls):
... print("Hello FishC")
那么直接使用 类名.函数() 的方式调用就会报错:
>>> Hello.print_hello()
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
Hello.print_hello()
TypeError: print_hello() missing 1 required positional argument: 'cls'
但是,只需要在类里面的函数名上方加上一个 @classmethod 修饰符:
>>> class Hello(object):
... @classmethod
... def print_hello(cls):
... print("Hello FishC")
那么问题就迎刃而解了:
>>> Hello.print_hello()
Hello FishC
因为给 @classmethod 修饰过后,print_hello() 就变成了类方法,可以直接通过 Hello.print_hello() 调用,而无需绑定实例对象了。
|