相关概念
1:实例方法
除了静态方法与类方法外,类的其他方法都属于实例方法。
实例方法隐含的参数为类实例self。
实例方法需要将类实例化后才可以调用,如果使用类直接调用实例方法,需要显示地将实例对象作为参数传入。
**直接用类调用实例方法代码**:
class ClassA():
def funcA(self):
print('Hello world')
# 使用实例调用实例方法
c = ClassA()
# ca.funcA() -----类实例化后,调用实例方法,输出结果为Hello world
# 如果使用类直接调用实例方法,需要显式地将实例作为参数传入
ClassA.funcA(c) ----类直接调用,需要显示地将实例对象作为参数传入,输出结果为Hello world
2:静态方法
静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,主要是一些逻辑属于类,但是和类本身没有交互,即在静态方法中,不会涉及到类中的方法和属性的操作。可以理解为将静态方法存在此类的名称空间中。事实上,在python引入静态方法之前,通常是在全局名称空间中创建函数。
静态方法可以被类或实例对象访问
**静态方法代码:**
import time
class TimeTest(object):
def __init__(self,hour,minute,second):
self.hour = hour
self.minute = minute
self.second = second
@staticmethod
def showTime():
return time.strftime("%H:%M:%S", time.localtime())
#t = TimeTest(2,10,10)
#nowTime = t.showTime() --- 实例对象调用静态方法
#输出为:23:08:13
# print (TimeTest.showTime()) ----类直接调用静态方法
#输出为23:08:13
备注:
Python使用静态方法类似函数工具使用,一般尽量少用静态方法。
Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的:
1)静态方法无需传入self参数,类成员方法需传入代表本类的cls参数;
2)从第1条,静态方法是无法访问实例变量的,而类成员方法也同样无法访问实例变量,但可以访问类变量;
3)静态方法有点像函数工具库的作用,而类成员方法则更接近类似Java面向对象概念中的静态方法。
3:类方法
类方法可以通过类直接调用,或通过实例直接调用。但无论哪种调用方式,方法隐含的参数为类本身cls
**类方法代码:**
class Student(object):
school='szu'
@staticmethod
def printmassage(a):
print(a)
s1=Student()
Student.printmassage('school') ---类直接调用 输出为szu
s1.printmassage('school') ----实例对象直接调用,输出为szu
实例方法和类方法区别:
首先形式上的区别,实例方法隐含的参数为类实例self,而类方法隐含的参数为类本身cls。 静态方法无隐含参数,主要为了类实例也可以直接调用静态方法。
所以逻辑上,类方法被类调用,实例方法被实例调用,静态方法两者都能调用。主要区别在于参数传递上的区别,实例方法悄悄传递的是self引用作为参数,而类方法悄悄传递的是cls引用作为参数。
4:总结-代码
下面我们在同一个程序中使用实例方法,类方法,静态方法,对比输出结果。
#定义一个类,包含以上三种方法
class A:
#类属性
explanation = 'this is my programs'
#普通方法,或实例方法
def normalMethod(self,name):
print(self.explanation)
#类方法,可以访问类属性
@classmethod
def classMethod(cls,explanation):
print(cls.explanation)
#静态方法。不可以访问类属性
@staticmethod
def staticMethod(explanation):
print(explanation)
a = A() #a 是实例对象
a.explanation = 'this is new'
# print(a.normalMethod('explanation')) #实例调用实例方法,所以结果为 this is new,实例对象可以修改类的属性
# print(A.normalMethod('explanation')) # 类不能调用实例方法
# print(a.classMethod('explanation')) #类方法可由实例对象或者类调用,因为传入了cls参数,
# print(A.classMethod('explanation')) #两者输出结果都是this is my programs
# print(a.staticMethod('my')) # 静态方法两者都可以访问,直接输出传入方法的值
# print(A.staticMethod('explanation')) # 两者输出结果都是 explanation
首先来看实例方法:
print(a.normalMethod('explanation')) #输出结果为:this is new,因为实例对象重新赋予了类的属性
类方法访问实例方法时,会报错:
print(A.normalMethod('explanation')) ##报错,因为类不能调用实例方法
总结:所以实例方法(普通方法)应该由实例调用,类不能调用
再来看类方法:
print(a.classMethod('explanation')) #输出结果this is my programs
print(A.classMethod('explanation')) #输出结果this is my programs
注意这里的输出结果是:this is my programs,实例方法输出的结果是:this is new,类中定义的属性explanation=’this is my programs‘,与实例化修改后的a.explanation = 'this is new’结果无关
总结:类方法可以由类调用,而且因为传入了参数cls,故也可以由实例来调用
最后来看静态方法:
print(a.staticMethod('testing coding one')) # 输出testing coding one
print(A.staticMethod('testing coding two')) # 输出testing coding two
总结:静态方法可以被实例对象和类访问,直接输出传入方法的值
归纳成一张表:
实例方法(普通方法) | 类方法 | 静态方法 | |
---|---|---|---|
实例调用a=A() | a.normalMethod(x) | a.classMethod(x) | a.staticMethod(x) |
类调用A | 不能调用 | A.classMethod(x) | A.staticMethod(x) |
所以实例方法的权限是最高的,只有实例对象可以访问。
而静态方法,实例对象和类方法都可以访问。