python内部装饰器@classmethod, @staticmethod, @property

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/brink_compiling/article/details/78723861

python面向对象编程中经常会用到三个装饰器语法:@classmethod, @staticmethod, @property。因为之前学习了下装饰器,所以在此了解一下python内置的三个装饰器。

@staticmethod和@classmethod

面向对象中类的方法一般有实例方法和静态方法两种,实例方法的调用需要先创建类的实例对象,而静态方法可以直接可以通过类名来调用。在python中使用@staticmethod或@classmethod,就可以不需要实例化调用方法,从而达到静态方法的效果(其实静态方法又称为类方法,python的这两个装饰器翻译过来恰好对应这一概念的两个名称)。
静态方法利于组织代码,把某些应该属于某个类的函数放到那个类里去,同时有利于命名空间的整洁。
虽然@staticmethod和@classmethod都可以达到静态方法的效果,但它们也存在着一些区别。
在使用时:
@staticmethod不需要像其他实例方法那样添加一个表示自身对象的self参数。这个很像我们平时所说的静态方法。
@classmethod也不需要self参数,但需要一个表示自身类的cls参数。因为持有这个cls参数,该装饰器下的方法可以来调用类的属性、方法,实例化对象等。更重要的也是区别与在函数内部直接使用类名调用自身类的方式在于,有了cls参数,当进行类的继承时,cls会变成子类本身,避免了硬编码,而使用类名调用自身类会在继承时无法更新到子类。
下面提供一个使用这两个装饰器的实例,代码如下:

class Obj(object):
    bar = 1

    def foo(self):
        print('foo')
    def from_j(self, p):
        Obj.foo()

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

    @classmethod
    def class_foo(cls):
        print('class_foo')
        print(cls.bar)
        cls().foo()
        print('class_static_foo')
        cls.static_foo()

Obj.static_foo()
Obj.class_foo()
'''
static_foo
1
class_foo
1
foo
class_static_foo
static_foo
1
'''

这里有个StackOverflow问题深入地讨论了@classmethod和@staticmethod的含义。

@property

这个装饰器的作用一句话来概括就是把类中一个方法变成属性调用。如下例:

class Student(object):

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value

s = Student()
s.score = 60 # 实际转化为s.set_score(60),增加了参数检查
s.score # 实际转化为s.get_score()

由上例可见,将一个类的方法变成属性,只需要加上@property就可以了。同时与其配套使用的是装饰器@score.setter,负责把一个setter方法变成属性赋值。如果想要这个属性是只读的,则可以省略@score.setter。
通过这种方式,可以用简短的代码,封装类内部的属性,既没有改变外部访问普通属性的方式,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。

猜你喜欢

转载自blog.csdn.net/brink_compiling/article/details/78723861