python里,对于类的各种方法也有着自己的定义。和java类似,有静态方法,实例方法。但是不同于java的是,它有一个特殊的方法,叫类方法。
前面讲过了,静态方法和java中的概念一致,直接使用类名.静态方法名去调用,在python中要由装饰器@staticmethod来注明。
1. 类方法及其使用
类方法是由装饰器@classmethod来注明的方法,它的使用需要遵守一定的规则:
- 类方法内部可以直接访问类属性、实例方法、类方法,但无法访问实例属性
- 调用其他类方法时,不用传递cls参数;但调用其他实例方法时,要传递cls参数
- 在类方法内部调用的实例方法,接收的是一个类对象而不是实例对象,当实例方法绑定实例属性时,在实例方法打印的仍然是类属性;表明类方法无法访问实例属性
- 一个类只有一个类对象,即使通过实例对象调用类方法,传递的仍然是类对象的引用,所有类方法都被同一个类对象引用
class Employee:
name = ''
age = 24
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def work(cls, h, e, t)
print(f"{cls.name} is age {cls.age} works {h} hours a day.")
cls.work_overtime(e) # 类方法中调用类方法,传参不需要加cls
cls.sign_in(cls, t) # 类方法中调用实例方法,传参要加cls
@classmethod
def work_overtime(cls, e)
print(f"{cls.name} works overtime {e} hours.")
def sign_in(self, t):
print(f"{self.name} signs in at {t}.")
if __name__ == '__main__':
e = Employee('yangyang', 28)
e.work(8, 2, '9:00')
对于类方法,内部调用类方法,传参不需要加cls, 但如果调用实例方法,传参得加cls。不管是调用类方法还是实例方法,都得用cls去调用。
2. 如果方法内部既需要访问实例属性,又需要访问类属性,应该定义成什么方法?
答:实例方法,因为实例方法可以通过类名.属性名访问类属性,而类方法无法访问实例属性
class Person:
name = "cool man"
def self_m(self):
Person.name = "yup" # 修改类属性
print(self.name) # 打印实例属性
p = Person()
p.name = "bad man"
p.self_m()
Person.self_m(Person) #
运行结果
由上可得知,类也可以调用实例方法,传参类,则调用类的属性,打印出来的是类的属性。