@classmethod
有的时候在类中会有一种情况,就是这个方法并不需要使用每一个对象属性
因此 这个方法中的self
参数一个完全无用的参数,使用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 25 26 27 28 29 30 31 32 33 34 35 36 37
| class A: __count = 0
def __init__(self, name): self.name = name self.__add_count()
@classmethod def __add_count(cls): print(cls, A) A.__count += 1
@classmethod def show_count(cls): print(cls.__count) return A.__count
def show_count_self(self): print(self)
obj = A('baozi') print(A._A__add_count)
<class '__main__.A'> <class '__main__.A'> <bound method A.__add_count of <class '__main__.A'>>
|
本质上 :
@classmethod
一个方法不用对象属性但是使用静态属性 – 类方法@classmethod
某一个方法被创造出来,就是为了进行对静态变量进行操作
@staticmehtod
根本不涉及到对象,所以这个方法就应该被定义成 类方法(被@classmethod
装饰)
调用这个类方法,可以使用对象调用,也可以使用类调用
但是这个方法的默认参数永远是当前类的命名空间,而不是对象的
@staticmethod
如果一个类中的方法不用 对象属性 也不用 静态属性 – 静态方法@staticmethod
那实际上这个方法就是一个普通的函数
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 User(object):
@staticmethod def login(arg1, arg2): return (arg1 + arg2)
def show(self): print('---->show') print('---self--',self.login(1, 3)) print('class--',User.login(123, 31))
print(User.login(1,2)) print(User().show())
3 ---->show ---self-- 4 class-- 154
|
一个不需要用到对象命名空间中的变量的方法,就不是一个对象方法,就应该是一个普通的函数
方法的查找的顺序:
类是直接在自己的空间找到类 类这个方法
对象先在自己的空间找,找不到,就到类的空间找
classmethod
staticmethod
使用场景说明:
用哪一个命名空间的名字,就定义的不同的方法
self
只要用self
就是普通方法,只能用对象调
Classmethod
只要cls 就是类方法,可以用类,可以用对象
Staticmethod
啥用不用 就是静态方法 ,可以用类,可以用对象
|
普通的方法 |
类方法 |
静态方法 |
默认参数 |
self |
cls |
无 |
操作变量 |
操作对象属性 |
操作静态属性 |
既不操作对象属性,也不操作类的属性 |
所属的命名空间 |
类 |
类 |
类 |
调用方式 |
对象 |
类/对象 |
类/对象 |
对应的装饰器 |
无 |
@classmethod |
@staticmethod |
@property
把一个方法伪装成属性,
下面例子中计算圆面积的公式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Cirecle: def __init__(self, r): self.r = r
@property def area(self):
return pi * self.r ** 2
def perimeter(self): return self.r * pi * 2
c1 = Cirecle(5)
print(c1.area)
78.53981633974483
|
某一个属性需要被私有,但是有需要可以被外部查看, 这种情况,把这个属性通过方法,`property 伪装成属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Person:
def __init__(self, name): self.__name = name
@property def get_name(self): return self.__name
ari = Person('arimiage')
print(ari.get_name)
arimiage
|
Property 修改属性值
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| class Person:
def __init__(self, name): self.__name = name
@property def name(self): return self.__name
@name.setter def name(self, new_name): if isinstance(new_name, str): self.__name = new_name
@name.deleter def name(self): print('gogoog') del self.__name
def get_name(self): return self.__name
ari = Person('arimiage') {'_Person__name': 'arimiage'}
print(ari.get_name)
ari.name = 'fgo' {'_Person__name': 'fgo'} print(Person.__dict__) print(ari.__dict__) print(ari.name)
del ari.name {} 对象空间为空
|
装饰器