## 类方法
**普通的方法**
class A:
def func(self):
print(self)
a1 = A()
a1.func()
# 结果:a1的内存地址
# <__main__.A object at 0x00FACEB0>
**调用普通方法必须要传一个参数**
class A:
def func(self): # 类里面的普通方法
print(self)
@classmethod # 类方法的装饰器
def fun1(cls):
print(cls)
a1 = A()
a1.func() # 对象调用self,将对象本身传给self
A.func(a1) # 类名点方法,主动传的对象
#结果
# <__main__.A object at 0x030E6450>
# <__main__.A object at 0x030E6450>
**类方法:通过类名调用的方法,类方法中第一个参数约定俗成是cls,python自动将类名(类空间)传给cls**
class A:
def func(self): # 类里面的普通方法
print(self)
@classmethod # 类方法的装饰器
def func1(cls):
print(cls)
A.func1() # 类名点方法,主动传的对象
# 结果
# <class '__main__.A'>
**对象可以调用类方法,传给cls的是类本身。(对象调用普通方法,传给self的是对象实例本身)**
class A:
def func(self): # 类里面的普通方法
print(self)
@classmethod # 类方法的装饰器
def func1(cls):
print(cls)
a1 = A()
a1.func1()
#结果
#<class '__main__.A'>
**类方法应用场景:**
1.类中有些方法是不需要传入对象,不要对象参与。
比如:要实现Alex2
class A:
name = "Alex"
count = 1
def func1(self): # 此方法无需对象参与
return A.name + str(A.count + 1)
方法一
A.func1(111) # 这样可以实现,但是不要用类名调用方法(除了类方法)
方法二
a1 = A() # 但是这个功能无需对象参与,非要实例化一个对象,不太合理
print(a1.func1())
这个时候,无需对象参与的方法,就需要用类方法
class A:
name = "Alex"
count = 1
@classmethod
def func1(cls): # 此方法无需对象参与
return A.name + str(A.count + 1)
print(A.func1())
#结果:Alex2
代码可以改进一下,cls接受的就是类空间
class A:
name = "Alex"
count = 1
@classmethod
def func1(cls): # 此方法无需对象参与
return cls.name + str(cls.count + 1)
print(A.func1())
2.对类中的静态变量进行改变的时候,要用到类方法
3.继承中,父类得到子类的类空间
class A:
name = "Alex"
count = 1
@classmethod
def func1(cls): # 此方法无需对象参与
print(cls)
class B(A):
pass
B.func1() # 子类通过类名执行父类的方法,并将子类的类名空间传给父类
# 结果
# <class '__main__.B'>
面试题:
class A:
age = 22
@classmethod
def func1(cls): # 此方法无需对象参与
# 对B类的所有内容可以进行修改
print(cls.age)
class B(A):
age = 12
B.func1() # 子类通过类名执行父类的方法,并将子类的类名空间传给父类
# 结果
# 12
思考,如果不用类方法,父类的某个方法如何得到子类空间里的任何东西
其实,在父类里面任意定义一个函数就可以
如下
class A:
age = 22
@classmethod
def func1(cls): # 此方法无需对象参与
# 对B类的所有内容可以进行修改
print(cls.age)
def func2(self):
print(self) # self就是子类的对象空间,就能得到空间的任意值
class B(A):
age = 12
b1 = B()
b1.func2()
# 结果 (B的对象空间)
# <__main__.B object at 0x00866550>
这样的话,类方法和普通方法的区别就是:
**类方法:传进去的是类空间,在父类里面对子类既能查,也能改**
**普通方法:传进去的对象空间,在父类里面对子类只能访问,查
没有优劣,看需求绝对**
## 静态方法
不需要传对象,和类名空间,只是一个普通的方法定义到函数中
class A:
@staticmethod
def func1(): # 不需要传对象,和类名空间
print(666)
A.func1()
# 结果
# 666
**静态方法和一个普通函数(不定义在类里面的)的区别**
1.代码块,清晰。将函数分类。把相关的方法,放在一个类里面
2.复用性。可以被继承。
## 总结:
**属性:将方法伪装成一个属性,代码上没有提升,只是更合理**
@property
@属性名.setter
@属性名.deleter
**类方法:**
@classmethod
只能有类名调用(对象调用也行,传给cls参数的也是该对象的所属类)
使用场景:
1,无需对象参与
2.对象中的静态变量进行修改
3.在父类中类方法得到子类的类空间,为所欲为
**静态方法**
@staticmethod
1.代码块,清晰。将函数分类。把相关的方法,放在一个类里面
2.复用性。可以被继承。
python2x 和python3区别
python2x :各种按照自己的习惯给python贡献源码(java的源码的习惯,C#源码的习惯),导致源码混乱,重复性高。(龟叔很生气)
python3x :龟叔重写,源码,优美,清晰,简单。