python中的类方法和静态方法-------------@classmethod和@staticmethod

一、python中的方法

python中存在三种方法,分别为常规方法(定义中传入self)、@classmethod修饰的类方法、@staticmethod修饰的静态方法。

class A(object):
    num = 0
    def __init__(self, index = 0):
        self.index = index 
    def foo(self, x):
        print("executing foo(%s,%s)" % (self, x))
        print('self:', self)
    @classmethod
    def class_foo(cls, x):
        print("executing class_foo(%s,%s)" % (cls, x))
        print('cls:', cls.num)
    @staticmethod
    def static_foo(x):
        print("executing static_foo(%s)" % x)




a = A()

以上面的代码为例,其中存在三种类型的方法。

1.常规方法foo()

常规方法定义时需要传入self参数,与类的实例绑定。也就是说调用时需要先实例化类,然后该实例才拥有foo()方法,通过A().foo()的方式来调用。不能直接用类A.foo()的方式来调用。

2.类方法class_foo()

用@classmethod修饰的方法需要传入cls参数(代表当前类),表示该方法与类绑定(不是实例),在该函数内部可以调用属于类的专有属性(一般来说定义在__init__外面的属性如上面的num)。可以直接用A.class_foo()来调用,当然也可以直接实例化,通过实例来调用。

3.静态方法static_foo()

用@staticmethod修饰的方法不需要传入任何参数,该方法内部不能访问类或者实例的属性,相当于定义在类外面的普通方法。

可以直接用A.static_foo()来调用或者通过实例来调用。

二、@classmethod和@staticmethod的异同

相同点:

  • 都可以直接用类名.方法(A.xx())的方式来访问,也可以通过实例来访问

不同点:

  • 构造时classmethod需要传入cls参数,staticmethod不需要
  • classmethod可以通过cls.来访问类的专有属性,staticmethod不能访问类的属性
  • classmethod可以被子类继承,能够判断出是父类还是子类调用

三、使用场景

1.classmethod用在构造前交互(即类实例化之前),一般是用来实现特殊的构造函数。

e.g我们定义了Date类,需要提供day,month,year三个参数进行初始化。

class Date(object):
    day = 0
    month = 0
    year = 0
    
    def __init__(self, day=0, month=0, year=0):
        self.day = day
        self.month = month
        self.year = year

但是如果我们有很多('dd-mm-yyyy')格式字符串的日期信息,想要把它们创建成Date类实例。此时我们需要将('dd-mm-yyyy')转化成三个整形变量,然后通过传递这些值实例化Date。

我们当然可以在函数外面做转化的事,然后去实例化,如下:

day, month, year = map(date_as_string.split('-'))
date1 = Date(day, month, year)

但是很明显转化这个功能放在类里面美观一点,但是一般的方法需要类实例化之后(调用了__init__之后)才可以使用,因此这里需要使用@classmethod

class Date(object):
    day = 0
    month = 0
    year = 0
    
    def __init__(self, day=0, month=0, year=0):
        self.day = day
        self.month = month
        self.year = year
    @classmethod
    def from_string(cls, date_as_string):
        day, month, year = map(date_as_string.split('-'))
        date1 = cls(day, month, year)


        return date1

date2 = Date.from_string('11-09-2012')

通过date2 = Date.from_string('11-09-2012')这样的方式就可以生成一个实例了。

2.某些不与实例交互的方法

不与实例交互就可以完成功能的方法虽然可以通过普通的实例化方法实现,但是实例化之后会浪费更多的时间与空间。因此使用staticmethod。

ps:staticmethod方法和一个定义在lei外面的函数没啥区别,为了美观和整洁才移到函数里面的。

猜你喜欢

转载自blog.csdn.net/goodxin_ie/article/details/89524280