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中的实例方法
实例方法是Python类中最常规,最常见的方法。实例方法之所以被称为实例方法,就是因为它能获取它所对应的实例自己独有的数据。假设有两辆车,都是通过汽车类创建而来,虽然它们都是汽车,但是它们可能自己独有的颜色,引擎,内饰等等。
实例方法必须拥有self这个形参(类似别的语言中的this指针),通过实例使用该方法时可省去不写。Self是Python中的一个特殊关键词。不管是在方法内还是在方法外,你都可以通过self来获取任何类的成员数据和方法,换言之,不通过self,你休想拿到成员数据和成员方法。
实例方法不需要装饰器,因为它已经是最常规的方法了。你创建的任何方法,如果不作特别声明,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中的静态方法
静态方法跟类相关,但是实现时并不需要,也不可以引用该类特有的数据,所以说
静态方法通常是“自给自足”的,只通过传递进来的实参来干活,于是呢
静态方法不需要self这个形参,甚至不一定需要通过实例来调用。
静态方法的声明需要使用 @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中的类方法
类方法不能引用实例的数据,但是它可以调用静态方法哦!
类方法不需要self,但是需要cls(class的意思),在调用时可以省去这个参数。
类方法的创建需要@classmethod。
类方法可能是三类方法中最让人感到疑惑的。但是它有它自己的用处,因为它可以对类本身进行操作,在一些比较大比较复杂的项目中可以发挥作用。吃撑了吧,看看黎姿
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的东东,还是有点(毛)用的。总而言之
实例方法:最常见,通过实例调用,可以访问该实例的数据。
静态方法:不能访问类中的其他任何东东,完全“自给自足”,可以通过类名直接调用。
类方法:可以调用静态方法,可以对类进行操作。