Python方法:@staticmethod和@classmethod

目录

一、@staticmethod和@classmethod的基本概念

二、@staticmethod和@classmethod的区别

三、@classmethod的应用场景

四、@staticmethod的应用场景

五、代码实现和对比

5.1 不使用@staticmethod和@classmethod

5.2 使用@classmethod

5.3 使用staticmethod

5.4 @classmethod与@staticmethod对比

小结


一、@staticmethod和@classmethod的基本概念

在常用的Python方法中,我们调用类的方法,每次都需要进行实例化,然后用实例化.方法进行调用。Python方法@staticmethod和@classmethod,可以被类直接调用,也可以被所有实例化对象共享。只要在某个方法前面加上@staticmethod或@classmethod就可以了,该方法通过调用staticmethod并且这样子还有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁

二、@staticmethod和@classmethod的区别

两种方法的区别

既然@staticmethod@classmethod都可以直接类名.方法名()来调用,那他们之间又有什么区别呢?别急,看下面

  • 首先
    • staticmethod(静态方法),需要一个装饰器语法(@staticmethod)将一个普通方法转换为静态方法
    • classmethod(类方法),需要一个装饰器语法(@classmethod)将一个普通方法转换为类方法
  • 然后
    • @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
    • @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
  • 最后
    • @staticmethod没有表示自身对象的self参数和自身类的cls参数,所以如果在@staticmethod中要调用到这个类的一些属性方法,如果我们使用实例化对象.方法名的时候,实例被忽略而类被使用,所以实际上还是类调用。
    • @classmethod因为有cls参数,当然是可以实例化对象.方法名,来避免硬编码。

三、@classmethod的应用场景

@classmethod 是 Python 中的一个装饰器(decorator),用于定义类方法。类方法是与类相关联的方法,而不是与类的实例相关联的方法。类方法在调用时,第一个参数是类本身,通常将其命名为 cls。使用 @classmethod 装饰器可以让 Python 解释器知道这是一个类方法,从而正确地处理它。

类方法可以通过类名调用,也可以通过类的实例调用。当使用类名调用类方法时,会自动将类作为第一个参数传递给方法。当使用类的实例调用类方法时,同样会自动将类作为第一个参数传递给方法。

四、@staticmethod的应用场景

@staticmethod也是一个Python中的装饰器(decorator),用于标记一个静态方法。

静态方法是一种在类中定义的方法,它与实例无关,因此可以在不创建类实例的情况下调用。与普通方法不同,静态方法没有self参数,因此它不能访问实例属性和方法

在Python中,使用@staticmethod装饰器可以将一个方法转换为静态方法,即使该方法定义在类中。使用静态方法的主要优点是可以在不创建类实例的情况下调用该方法,从而提高代码的灵活性和可重用性。

五、代码实现和对比

5.1 不使用@staticmethod和@classmethod

class Cat:
    def __init__(self,i):
        print('__init__: %d'%i)
    @staticmethod
    def eat():
        print('@staticmethod不需要self参数,实例调用函数实例不传入做参数')
        
c = Cat(1)
Cat.eat()

 输出结果:

__init__: 1
@staticmethod不需要self参数,实例调用函数实例不传入做参数

5.2 使用@classmethod

class Cat:
    def __init__(self,i):
        print('__init__: %d'%i)
    @classmethod
    def eat(cls):
        print('@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数')
        
c = Cat(1)
Cat.eat()

输出结果:

__init__: 1
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数

5.3 使用staticmethod

class Cat:
    def __init__(self,i):
        print('__init__: %d'%i)
    @classmethod
    def eat(cls):
        print('@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数')
        
c = Cat(1)
Cat.eat()

输出结果:

__init__: 1
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数

5.4 @classmethod与@staticmethod对比

@classmethod方法

class Cat:
    def __init__(self,i):
        print('__init__: %d'%i)
    @classmethod
    def eat(cls,name):
        print(name,'@classmethod因为有cls参数,当然是可以实例化对象.方法名,来避免硬编码')
        print('@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数')
        
c = Cat(1).eat('fish')
Cat.eat('fish')   # 因为被@classmethod装饰的函数,可以直接被类本身调用

输出结果:

__init__: 1
fish @classmethod因为有cls参数,当然是可以实例化对象.方法名,来避免硬编码
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数
fish @classmethod因为有cls参数,当然是可以实例化对象.方法名,来避免硬编码
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数

 @staticmethod方法

class Cat:
    def __init__(self,i):
        print('__init__: %d'%i)
    @staticmethod
    def eat(name):
        print(name,'@staticmethod没有表示自身对象的self参数和自身类的cls参数,实例化对象.方法名,实例被忽略而类被使用,所以实际上还是类调用')
        print('@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样')
        
c = Cat(1).eat('fish')
Cat.eat('fish')  # 静态方法无需实例化,也可以实例化后调用

输出结果:

__init__: 1
fish @classmethod因为有cls参数,当然是可以实例化对象.方法名,来避免硬编码
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数
fish @classmethod因为有cls参数,当然是可以实例化对象.方法名,来避免硬编码
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数

小结

  • classmethod尤其适合用在当我们需要在创建真正的类实例之前做一些预设置的情况,因为实例建立之前显然你是不能使用实例方法的,你只能使用classmethod,这样做的另一个好处就是你以后重构类的时候不必要修改构造函数,只需要额外添加你要处理的函数,然后使用装饰符@classmethod就可以了。相当于我们拥有了多样化的构造函数。

  • Python使用类时,通常需要为对象初始化绑定方法,绑定方法同样是对象,但是创建他们需要成本,而staticmethod就可以避免这些。

  • classmethod因为有cls参数,可以调用类的属性,类的方法等,避免了使用类名硬编码。classmethod既具有普通实例方法访问类名称空间的能力,又具有静态方法随意使用的灵活性。

  • 实例属性由实例更改,不会影响类属性。而类属性则可以由类方法 (classmethod)来更改。

猜你喜欢

转载自blog.csdn.net/weixin_43734080/article/details/129827013