python中的方法和装饰器

[TOC]

装饰器

python中的装饰器(decorator)是在pep 318中被首次引入,它的本质是一个函数这个函数是接受其它参数为参数,并且用一个新的,修改后的函数作为替换,最常见的装饰器就classmethod和staticmethod

def happy(f):
    return  lambda x:2*x



@happy
def haha(x):
    print "you can't see me"
    return 12*x


print haha(1)

方法

方法是作为类属性的函数
如果直接调用类方法,py2里会提示是一个未绑定的方法,py3里会提示这是一个函数

class happy():
    name = 'happy'

    def hh(self,ddd):
        return ddd

print happy.hh('aaa')

python3里,可以传入一个实例化的class进去,调用未绑定的方法

class happy():
    name = 'happy'

    def hh(self,ddd):
        return ddd

print(happy.hh(happy(),'aaa'))

静态方法 staticmethod

除了python3里传未绑定的类给类方法之外,还有个办法可以调用未绑定的类方法
就是静态方法

class happy():
    name = 'happy'

    @staticmethod
    def hh():
        return 111

print happy.hh()

静态方法就是定义类方法时候加一个staticclass的decorator,它有几个好处

  • 调用方法前,不必实例化方法,减少开销
  • 提高代码可读性
  • 可以在子类中覆盖静态方法

类方法 classmethod

classmethod是直接绑定到类的方法
类方法最有用的是创建工厂方法,也就是以特定方式实例化对象

类方法定义时候,总是要绑定到它附着的类上,而且它的第一个参数必须是类本身,比如

class happy():
    name = 'happy'

    @classmethod
    def hh(cls):
        return 111

print happy.hh()

抽象方法 abstactclass和abc

抽象方法是在基类里定义的,但是需要子类继续完善的方法
好多语言里,抽象方法只能定义,不能实现,py里抽象方法是可以实现一些通用功能,并且,通过super,在子类里被调用

如果不用abc,类被继承,但是抽象方法没重新实现的时候,抽象方法不被调用就不会报错
解决方案就是用abc,示例如下

import abc

class happy():
    __metaclass__ = abc.ABCMeta
    name = 'happy'

    @staticmethod
    @abc.abstractmethod
    def hh(ddd):
        return ddd.name + 'static'


print happy.hh('aaa')

混合使用三种方法

静态方法或者类方法可以和抽象方法混用
如果混用了,抽象方法在子类里,无须实例化,即可调用
示例如下

import abc


class happy():
    __metaclass__ = abc.ABCMeta
    name = 'happy'

    @staticmethod
    @abc.abstractmethod
    def hh(ddd):
        return ddd + 'static'


class haha(happy):

    def aa(self):
        return super(haha,self).name


print haha().hh('dd')

super

python比较牛逼的地方是支持mixin和多重继承,可以很方便的通过super函数,调用一个类的父类,那么问题来了,如果一个方法,再多个父类里都有,那么调用那个父类呢?这就涉及一个mro的算法,mro变换过多次,最近的一次是py2.3里实现的c3算法,C3算法解决了单调性问题和只能继承无法重写问题
python里的super算法,总体可以归结成一句话,自上到下,自左到右
把左边的类,从上到下遍历过了,才会遍历
就像下面的图,遍历顺序是a b d c e f
c3算法更具体解释可以参见官网



class D(object):
    pass

class E(object):
    pass

class F(object):
    pass

class C(E, F):
    pass

class B(D,E):
    pass

class A(B, C):
    pass

if __name__ == '__main__':
    print A.__mro__


                          6
                         ---
Level 3                 | O |                  (more general)
                      /  ---  \
                     /    |    \                      |
                    /     |     \                     |
                   /      |      \                    |
                  ---    ---    ---                   |
Level 2        3 | D | 4| E |  | F | 5                |
                  ---    ---    ---                   |
                   \  \ _ /       |                   |
                    \    / \ _    |                   |
                     \  /      \  |                   |
                      ---      ---                    |
Level 1            1 | B |    | C | 2                 |
                      ---      ---                    |
                        \      /                      |
                         \    /                      \ /
                           ---
Level 0                 0 | A |                (more specialized)
                           ---
    原文作者:russelllei
    原文地址: https://www.jianshu.com/p/7dd58c4f22dc
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞