浅析Python装饰器

Python装饰器的理解
装饰器一直不是很容易理解,在网上找了一篇文章对装饰器的解释是最好的。转给大家以共享。

Python中函数有一个装饰器的概念,今天,看核心编程中的函数一章的时候接触到了这个概念,炸一看来,讲的说明真实不好明白。于是写下本篇以示说明,提供给迷糊者。希望能对一些人起到一定的帮助

    装饰器的语法以@开头,接着是装饰器要装饰的函数的申明等。

其实总体说起来,装饰器其实也就是一个函数,一个用来包装函数的函数,装饰器在函数申明完成的时候被调用,调用之后申明的函数被换成一个被装饰器装饰过后的函数。

装饰器分为无参装饰和有参装饰

无参装饰很简单

定义方法如下:

比如先定义一个装饰方法:

def FirstDeco(func):

   print '第一个装饰器'

   return func

@FirstDeco

def test():

  print 'asdf'

....

申明完成之后显示

...     
第一个装饰器

可见装饰器在函数定义完成的时候被触发

然后,咱们运行test

获得asdf

多参装饰:

   多参装饰复杂一点,多参装饰的时候,装饰函数先处理参数,再生成一个新的装饰器函数,然后对函数进行装饰

具体代码如下:

>>> def deco(x):
...     print '%s 开始新装饰'
...     def newDeco(func):
...         def test(a,b):
...             print 'begin'
...             returnv = func(a,b)
...             print 'end'
...             return returnv
...         return test
...     return newDeco
... 

这里定义了一个装饰其函数deco,里面有一个参数x,这个时候,我们没有直接使用func作为装饰函数的参数,而是只用了参数x作为参数,之后定义一个新的装饰函数,newdeco,该函数才装饰

然后定义如下:

>>> @deco(3)
... def mytest(x,y):
...     if x>y:
...         print x
...     else:
...         print y
...         
%s 开始新装饰

运行之后的结果为

%s 开始新装饰
>>> mytest(3,4)
begin
4
end

参考资料:


装饰方法的产生:

Python2.2通过增加静态方法和类方法扩展了Python的对象模型。但是当时没有提供一个简化的语法去定义static/class方法,只得在定义好的方法尾部去调用staticmethod()/classmethod()方法达到目的。例如:


浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 class C:
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战    def meth (cls):
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战         浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战    meth = classmethod(meth)   # 使meth方法成为类方法

但是这样会造成一个问题:当一个方法比较长时,很容易忘记尾部的调用。为了简化这个操作一个新的语法被加了进来:方法装饰,以@开头后跟装饰方法 名,如@staticmethod/@classmethod,由此产生出decorator方法及decorator模式。现在我们可以这样写:


浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 class C:
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战    @classmethod
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战    def meth (cls):
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战

可以对一个方法应用多个装饰方法:


浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 @A
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 @B
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 @C
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 def f ():
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战      浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 #等价于下面的形式,Python会按照应用次序依次调用装饰方法(最近的先调用)
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 def f(): 
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 f = A(B(C(f)))
装饰方法解析:

每个decorator只是一个方法, 可以是自定义的或者内置的(如内置的@staticmethod/@classmethod)。decorator方法把要装饰的方法作为输入参数,在函数体内可以进行任意的操作(可以想象其中蕴含的威力强大,会有很多应用场景), 只要确保最后返回一个可执行的函数即可(可以是原来的输入参数函数, 或者是一个新函数)。decorator的作用对象可以是模块级的方法或者类方法。decorator根据应用时的参数个数不同分为两类:无参数 decorator,有参数decorator。下面分别介绍。

无参数decorator:


浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 def deco(func):
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     """无参数调用decorator声明时必须有一个参数,这个参数将接收要装饰的方法"""
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     print "Enter decorator"     #进行额外操作
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     func.attr = 'decorated'     #对函数进行操作,增加一个函数属性
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     return func   #返回一个可调用对象(此例还是返回作为输入参数的方法)
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战                       #返回一个新函数时,新函数可以是一个全局方法或者decorator函数的内嵌函数,
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战                       #只要函数的签名和被装饰的函数相同
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 @deco
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 def MyFunc():   #应用@deco修饰的方法
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     print "Enter MyFunc"
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 MyFunc()     #调用被装饰的函数

注意:当使用上述方法定义一个decorator方法时,函数体内的额外操作只在被装饰的函数首次调用时执行,如果要保证额外操作在每次调用被装饰的函数时都执行,需要换成如下的写法:


浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 def deco(func):
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     def replaceFunc():     #定义一个内嵌函数,此函数包装了被装饰的函数,并提供额外操作的代码
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战         print "Enter decorator"     #进行额外操作
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战         return func()    #产生对被装饰函数的调用
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     return replaceFunc   #由于返回的是这个新的内嵌函数,所以确保额外操作每次调用得以运行
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 @deco
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 def MyFunc():   #应用@deco修饰的方法
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     print "Enter MyFunc"
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 MyFunc()     #调用被装饰的函数

有参数decorator:


浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 def decoWithArgs(arg):
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     """由于有参数的decorator函数在调用时只会使用应用时的参数而不接收被装饰的函数做为参数,
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战        所以必须返回一个decorator函数, 由它对被装饰的函数进行封装处理"""
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     def newDeco(func):    #定义一个新的decorator函数
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战         def replaceFunc():    #在decorator函数里面再定义一个内嵌函数,由它封装具体的操作
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战             print "Enter decorator"     #进行额外操作
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战             return func()    #对被装饰函数进行调用
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战         return replaceFunc
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     return newDeco    #返回一个新的decorator函数
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 @decoWithArgs("demo")
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 def MyFunc():    #应用@decoWithArgs修饰的方法
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     print "Enter MyFunc"
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战     
浅析Python装饰器 - 丅壹站-火星 - 夏Ⅰ战 MyFunc()    #调用被装饰的函数

当我们对某个方法应用了装饰方法后, 其实就改变了被装饰函数名称所引用的函数代码块入口点,使其重新指向了由装饰方法所返回的函数入口点。由此我们可以用decorator改变某个原有函数的功能,添加各种操作,或者完全改变原有实现。

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值