python面向对象@staticmethod和@classmethod

记录一下用法,方便自己查询

参考

  • @classmethod、 @staticmethod、 @property、类装饰器
  • python中staticmethod与classmethod两种装饰器的异同

@classmethod

在C++的面向对象中,有static修饰的静态方法,其可以被类所访问,也可以被实例化的对象访问。在python的类中与之类似的是@classmethod,即类方法。

实例

实例如下所示:

class Dog:
    # 类属性
    dogsum = {}
    def __init__(self, name, gender, age, type) -> None:
        self.name = name
        self.gender = gender
        self._age = age
        self.type = type
        Dog.dogsum.setdefault(type, 0)
        Dog.dogsum[type] += 1

    @classmethod
    def get_sum(cls, type):
        return cls.dogsum[type]
    
dog = Dog("xiaohei", "male", 5, "tugou")
dog = Dog("xiaohong", "female", 6, "tugou")
dog = Dog("xiaohuang", "male", 7, "taidi")


print(Dog.dogsum)
print(Dog.get_sum("tugou"))

结果:

{'tugou': 2, 'taidi': 1}
2

可以看到,我们在类中定义了一个类属性dogsum,统计不同的type的dog的数目,在创建类时会对dogsum进行修改。因为该属性是一个类属性,所以应该定义一个类方法对其访问,即get_sum方法。由@classmethod修饰后,其相对于普通的类的方法,他不会传入参数self,而是会传入参数cls,代表这个类。此后该方法就可以通过类调用,同时也可以由任意一个实例化的对象调用。
如果不使用@classmethod修饰,尝试如下:

class Dog:
    # 类属性
    dogsum = {}
    def __init__(self, name, gender, age, type) -> None:
        self.name = name
        self.gender = gender
        self._age = age
        self.type = type
        Dog.dogsum.setdefault(type, 0)
        Dog.dogsum[type] += 1


    def get_sum(self, type):
        return Dog.dogsum[type]


dog0 = Dog("xiaohei", "male", 5, "tugou")
dog1 = Dog("xiaohong", "female", 6, "tugou")
dog2 = Dog("xiaohuang", "male", 7, "taidi")

print(Dog.dogsum)
print(dog0.get_sum("tugou"), dog1.get_sum("tugou"))

结果:

{'tugou': 2, 'taidi': 1}
2 2

可以看到,还是可以实现,但是就不如使用@classmethod修饰后更加规范。

@staticmethod

对于@classmethod,其需要传入参数cls代表这个类,而对于@staticmethod,其不需要传入任何与该类有关的参数,所以更像一个与该类没有人任何关系的方法。当时将其放入相关的类中,会更系统。

你可能感兴趣的:(python,python,开发语言)