内置的装饰器和普通的装饰器原理是一样的,只不过返回的不是函数,而是类对象。内置的装饰器有@property,@staticmethod,@classmethod

@property

@property装饰器就是负责把一个方法变成属性调用的,也就是调用时不需要括号()。

property的两种写法
写法1,不使用@语法糖

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class MathScore:
    def __init__(self, score):
        if score < 0:
            raise ValueError("Score can't be negative number!")
        self.__score = score

    def check(self):
        if self.__score >= 60:
            return 'pass'
        else:
            return 'failed'

    def __get_score__(self):
        return self.__score

    def __set_score__(self, value):
        if value < 0:
            raise ValueError("Score can't be negative number!")
        self.__score = value

    score = property(__get_score__, __set_score__)

m = MathScore(50)
print(m.score)
m.score = 90
print(m.score)
print(m.check())

执行以上程序会输出如下结果:

1
2
3
50
90
pass

写法2,使用@语法糖

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class MathScore():
    def __init__(self, score):
        if score < 0:
            raise ValueError("Score can't be negative number!")
        self.__score = score

    def check(self):
        if self.__score >= 60:
            return 'pass'
        else:
            return 'failed'

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

    @score.setter #注意方法名称要与上面一致,否则会失效
    def score(self, value):  
        if value < 0:
            raise ValueError("Score can't be negative number!")
        self.__score = value

m = MathScore(50)
print(m.score)
m.score = 90
print(m.score)
print(m.check())

执行以上程序会输出如下结果:

1
2
3
50
90
pass

定义只读属性,只定义getter方法,不定义setter方法。 例如

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class MathScore():
    def __init__(self, score, name):
        if score < 0:
            raise ValueError("Score can't be negative number!")
        self.__score = score
        self.__name = name

    def check(self):
        if self.__score >= 60:
            return 'pass'
        else:
            return 'failed'

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

    @score.setter
    def score(self, value):
        if value < 0:
            raise ValueError("Score can't be negative number!")
        self.__score = value

    @property #只读属性
    def nameOutput(self):
        return self.__name

m = MathScore(40,"Math")
print(m.score)
print(m.nameOutput)
m.score = 90
print(m.score)
print(m.nameOutput)

执行以上程序会输出如下结果:

1
2
3
4
40
Math
90
Math

score是可读写属性,而nameOutput就是一个只读属性。

@staticmethod

类静态方法装饰器

@classmethod

类方法装饰器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Parent:
    name = "I'm the parent"
    @staticmethod
    def print_name_by_static():
        print(Parent.name)

    @classmethod
    def print_name_by_class(cls):
        print(cls.name)
class Child(Parent):
    pass

if __name__ == "__main__":
    p = Parent()
    p.print_name_by_static()
    p.print_name_by_class()
    Parent.print_name_by_static()
    Parent.print_name_by_class()
    print('=====================')
    c = Child()
    c.print_name_by_static()
    c.print_name_by_class()
    Child.print_name_by_static()
    Child.print_name_by_class()

执行以上程序会输出如下结果:

1
2
3
4
5
6
7
8
9
I'm the parent
I'm the parent
I'm the parent
I'm the parent
=====================
I'm the parent
I'm the parent
I'm the parent
I'm the parent
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Parent:
    name = "I'm the parent"
    @staticmethod
    def print_name_by_static():
        print(Parent.name)

    @classmethod
    def print_name_by_class(cls):
        print(cls.name)
class Child(Parent):
    name = "I'm the child"

if __name__ == "__main__":
    p = Parent()
    p.print_name_by_static()
    p.print_name_by_class()
    Parent.print_name_by_static()
    Parent.print_name_by_class()
    print('=====================')
    c = Child()
    c.print_name_by_static()
    c.print_name_by_class()
    Child.print_name_by_static()
    Child.print_name_by_class()

执行以上程序会输出如下结果:

1
2
3
4
5
6
7
8
9
I'm the parent
I'm the parent
I'm the parent
I'm the parent
=====================
I'm the parent
I'm the child
I'm the parent
I'm the child

通过上面得出的结果可以分析: 由@staticmethod修饰的方法叫静态方法,由@classmethod修饰的方法叫类方法。

共同点:
静态方法和类方法都可以用类或其实例进行调用。

不同点:
类方法在定义时,需要名为cls的类似于self的参数。cls参数是自动绑定到当前类的。


转载请注明本网址。