Python使用技巧(十五):静态类方法@staticmethod和@classmethod

零、介绍静态类方法@staticmethod和@classmethod的关系

class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
  • 实例方法

MyClass调用的第一个方法method是常规实例方法。这是您大多数时候会使用的基本,简洁的方法类型。您可以看到该方法采用一个参数,self该参数指向MyClass该方法被调用的时间的实例(但当然实例方法可以接受多个参数)。

通过该self参数,实例方法可以自由访问同一对象上的属性和其他方法。在修改对象状态时,这赋予了他们很多功能。

实例方法不仅可以修改对象状态,而且还可以通过self.__class__属性访问类本身。这意味着实例方法也可以修改类状态。

  • 类方法

让我们将其与第二种方法进行比较MyClass.classmethod。我用@classmethod装饰器标记了此方法,以将其标记为类方法。

self类方法不接受参数,而是在调用方法时使用cls指向类的参数,而不是对象实例。

因为类方法只能访问此cls参数,所以它不能修改对象实例状态。那将需要访问self。但是,类方法仍然可以修改适用于该类所有实例的类状态。

  • 静态方法

第三种方法MyClass.staticmethod用@staticmethod装饰器标记,以将其标记为静态方法。

这种类型的方法既不带参数self也不带cls参数(但是可以自由接受任意数量的其他参数)。

因此,静态方法无法修改对象状态或类状态。静态方法在可以访问哪些数据方面受到限制-它们主要是为方法命名空间的一种方法。

一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。

既然@staticmethod和@classmethod都可以直接类方法名()来调用,那他们有什么区别呢?从它们的使用上来看,@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。

如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。
案例如下:

class A(object):  
    bar = 1  
    def foo(self):  
        print( 'foo' )  

    @staticmethod  
    def static_foo():  
        print( 'static_foo' ) 
        print( A.bar)  

    @classmethod  
    def class_foo(cls):  
        print('class_foo' ) 
        print( cls.bar)  
        cls().foo()  
###执行  
A.static_foo()  
A.class_foo()

结果:

static_foo
1
class_foo
1
foo

事实上,就是不用对象调用,而是直接用类来调用。Python类中普通方法调用自身的静态方法,使用self.函数名()即可。

案例如下:

In [5]: import numpy as np
   ...: 
   ...: class A(object):
   ...:     def foo(self):
   ...:         self.static_foo()
   ...: 
   ...:     @staticmethod
   ...:     def static_foo():
   ...:         print( 'This is static_foo.')
   ...: 
   ...: if __name__ == "__main__":
   ...:     test = A()
   ...:     test.foo()
   ...: 
This is static_foo.

结果:

This is static_foo.

一、Python三种类方法案例

  • 静态方法(staticmethod)
  • 类方法(classmethod)
  • 实列方法
    代码实现:
class TestFuc(object):
    def instance_fuc(self, x):
        print('instance_fuc(%s,%s)' % (self, x))
 
    @classmethod
    def class_fuc(cls,x):
        print('class_fuc(%s,%s)' % (cls,x))
 
    @staticmethod
    def static_fuc(x):
        print('static_fuc(%s)' % x)
 
 
test_fuc = TestFuc()
 
# 实例方法
test_fuc.instance_fuc(1)
# 类方法
test_fuc.class_fuc(1)
TestFuc.class_fuc(1)
 
# 静态方法
test_fuc.static_fuc(1)
TestFuc.static_fuc(1)

执行结果:

instance_fuc(<__main__.TestFuc object at 0x0000017EFA10DFC8>,1)
class_fuc(<class '__main__.TestFuc'>,1)
class_fuc(<class '__main__.TestFuc'>,1)
static_fuc(1)
static_fuc(1)

二、继承类中的区别

  • 子类的实例继承了父类的static_method静态方法,调用该方法,还是调用的父类的方法和类属性。
  • 子类的实例继承了父类的class_method类方法,调用该方法,调用的是子类的方法和子类的类属性。
    源码:
class Foo(object):
    X = 1
    Y = 2

    @staticmethod
    def averag(*mixes):  #一种变量代替多变量
        return sum(mixes) / 1

    @staticmethod
    def static_method():
        return Foo.averag(Foo.X, Foo.Y)

    @classmethod
    def class_method(cls):
        return cls.averag(cls.X, cls.Y)


class Son(Foo):
    X = 3
    Y = 5

    @staticmethod
    def averag(*mixes):
        return sum(mixes) / 2

p = Son()
print(p.static_method())
print(p.class_method())

结果:

3.0
4.0

引用文献:
https://www.cnblogs.com/flypig258/p/11428500.html
https://www.cnblogs.com/cgmcoding/p/13936684.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

源代码杀手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值