Python中实例方法、静态方法和类方法的重要区别

Python中的三类方法/函数

Python中有三类方法,实例方法(Instance Method)、静态方法(Static Method)和类方法(Class Method)。如果只是编写一些简单的Python脚本,那么了解这三类方法的区别没有什么大的鸟用。但是,如果是为了OOP,那么深入理解这三类方法还是非常有必要的。。。吧


开始之前:理解装饰器模式

了解这三类方法的区别之前,得要先了解装饰器模式(通常简称为装饰器)。装饰器听上去好复杂,好高大上,好怕怕啊,实际上很简单,很可爱,不怕不怕,摸摸头。装饰器不过是一些简单的函数。你可以自己写,也可以用第三方库的或者Python标准库里现成的装饰器。只要是个函数,那么它的存在必然是为了完成某件事情,或者说是任务(你问我函数体为空的函数完成了啥任务?你真的天真的认为它真的是空的,真的什么都没做吗?)装饰器和普通函数不同之处在于,
它的存在形式
(1)将某种逻辑施加在别的函数上,或者
(2)改变别的函数的某种行为;
它的存在意义
(1)代码的重复利用,或者
(2)将复杂的逻辑解耦为单独的小的逻辑。

这里是我写的一个记录函数运行时间的装饰器,很简单,可以参考以下

不使用装饰器和使用装饰器的演化过程,自己琢磨吧,完整例子点这里

def use_logging(func):
    logging.warn("%s is running" % func.__name__)
    func()

def foo():
    print('i am foo')

use_logging(foo)
    def wrapper():
        logging.warn("%s is running" % func.__name__)
        return func()   # 把 foo 当做参数传递进来时,执行func()就相当于执行foo()
    return wrapper

def foo():
    print('i am foo')

foo = use_logging(foo)  # 因为装饰器 use_logging(foo) 返回的时函数对象 wrapper,这条语句相当于  foo = wrapper
foo()                   # 执行foo()就相当于执行 wrapper()
def use_logging(func):

    def wrapper():
        logging.warn("%s is running" % func.__name__)
        return func()
    return wrapper

@use_logging
def foo():
    print("i am foo")

foo()

Python本身倾向于使用装饰器来定义静态方法或者类方法,客官吃颗栗子吧

class DecoratorExample:
  """ Example Class """
  def __init__(self):
    """ Example Setup """
    print('Hello, World!')

  @staticmethod
  def example_function():
    """ This method is decorated! """
    print('I\'m a decorated function!')

de = DecoratorExample()
de.example_function()

装饰器使用在函数或者类声明之前,以@打头,它是函数,但是不需在名称后面加上括号()。值得注意的是,一个函数或者类可以被多个装饰器装饰,运行的顺序一般是自下而上(使用过unit test mock模块的应该都已经知道了这个奇葩顺序),但是,呵呵,有空玩玩下面这个梨子吧

def first_decorator(func):
    print('--first--')

    def first_wrapper(*args, **kwargs):
        print('------first---%s---' % func.__name__)
        return func(*args, **kwargs)
    return first_wrapper


def second_decorator(func):
    print('--second--')

    def second_wrapper(*args, **kwargs):
        print('------second---%s---' % func.__name__)
        return func(*args, **kwargs)
    return second_wrapper

@first_decorator
@second_decorator
def test_func_1():
    print('excute %s' % inspect.stack()[0][3])

输出

--second--
--first--
------first---second_wrapper---
------second---test_func_1---
excute test_func_1

Python中的实例方法

  1. 实例方法是Python类中最常规,最常见的方法。实例方法之所以被称为实例方法,就是因为它能获取它所对应的实例自己独有的数据。假设有两辆车,都是通过汽车类创建而来,虽然它们都是汽车,但是它们可能自己独有的颜色,引擎,内饰等等。
  2. 实例方法必须拥有self这个形参(类似别的语言中的this指针),通过实例使用该方法时可省去不写。Self是Python中的一个特殊关键词。不管是在方法内还是在方法外,你都可以通过self来获取任何类的成员数据和方法,换言之,不通过self,你休想拿到成员数据和成员方法。
  3. 实例方法不需要装饰器,因为它已经是最常规的方法了。你创建的任何方法,如果不作特别声明,Python都会把它当作实例方法。惯例给个粒子
class DecoratorExample:
  """ Example Class """
  def __init__(self):
    """ Example Setup """
    print('Hello, World!')
    self.name = 'Decorator_Example'

  def example_function(self):
    """ This method is an instance method! """
    print('I\'m an instance method!')
    print('My name is ' + self.name)
 
de = DecoratorExample()
de.example_function()

Python中的静态方法

  1. 静态方法跟类相关,但是实现时并不需要,也不可以引用该类特有的数据,所以说
  2. 静态方法通常是“自给自足”的,只通过传递进来的实参来干活,于是呢
  3. 静态方法不需要self这个形参,甚至不一定需要通过实例来调用。
  4. 静态方法的声明需要使用 @staticmethod,继续吃个李子了解一下
class DecoratorExample:
  """ Example Class """
  def __init__(self):
    """ Example Setup """
    print('Hello, World!') 

  @staticmethod
  def example_function():
    """ This method is a static method! """
    print('I\'m a static method!')
 
de = DecoratorExample.example_function()

Python中的类方法

  1. 类方法不能引用实例的数据,但是它可以调用静态方法哦!
  2. 类方法不需要self,但是需要cls(class的意思),在调用时可以省去这个参数。
  3. 类方法的创建需要@classmethod
  4. 类方法可能是三类方法中最让人感到疑惑的。但是它有它自己的用处,因为它可以对类本身进行操作,在一些比较大比较复杂的项目中可以发挥作用。吃撑了吧,看看黎姿
class DecoratorExample:
  """ Example Class """
  def __init__(self):
    """ Example Setup """
    print('Hello, World!') 

  @classmethod
  def example_function(cls):
    """ This method is a class method! """
    print('I\'m a class method!')
    cls.some_other_function()

  @staticmethod
    def some_other_function():
    print('Hello!')
 
de = DecoratorExample()
de.example_function()

什么时候用什么方法

头好疼,还是不知道选哪个方法?还不如不知道这么多,心好累。其实,只要多加练习,多在项目上踩踩坑,多写一些bug,你大概就知道了!多了解一些Python OOP的东东,还是有点(毛)用的。总而言之
实例方法:最常见,通过实例调用,可以访问该实例的数据。
静态方法:不能访问类中的其他任何东东,完全“自给自足”,可以通过类名直接调用。
类方法:可以调用静态方法,可以对类进行操作。

你可能感兴趣的:(Python中实例方法、静态方法和类方法的重要区别)