上节课讲到实例方法,类方法和静态方法的构造,这节课主要使用一个示例来讲一下实例方法,类方法和静态方法的具体使用,比较一下这三种方法的调用区别。
首先创建一个类。
class Person:
name = 'jerry'
def eat(self, food):
print('他在吃' + food, self)
@classmethod
def run(cls):
print('小明会跑步', cls)
@staticmethod
def haha():
print('小明在大笑')
我们来看看这三种方法的调用。
1.实例方法
p = Person()
p.eat('水果') # 这里使用p来调用实例方法,所以解释器会把p当做方法中的self直接传递进去,我们只要写另外的参数就可以
print(p) # 这里的p和self的内存地址一样
Person.eat('aaa', '西瓜') # 也可以使用类来调用内部的实例方法,但是要传入两个参数,第一个是对象,不推荐
2.类方法:可以通过类和实例名调用
Person.run()
p.run() # 这里是把实例忽略,但是向上溯源到实例所在的类,并把类作为参数穿个cls
# 如果使用子类来调用类方法,则会把子类传递给cls,后面继承中详解
3.静态方法
Person.haha() # 使用类调用静态方法
p.haha() # 使用实例调用静态方法
4.使用三种方法访问类属性和实例属性
class Person:
name = 'jerry'
def eat(self):
print('他在吃', self)
print(self.name)
print(self.age)
@classmethod
def run(cls):
print('小明会跑步', cls)
print(cls.name)
print(cls.age)
@staticmethod
def haha():
print('小明在大笑')
print(Person.name)
print(Person.age)
p = Person()
p.age = 22 # 增加一个实例属性
通过三个方法来访问实例属性age和类属性name,实例属性通过self可以拿到实例对象,所以实例属性和类属性都能通过self访问到。
print(Person.eat(p)) # 能访问到实例属性age和类属性name
print(p.eat()) # 能访问到实例属性age和类属性name
返回结果:
他在吃 <__main__.Person object at 0x0000000002312070>
jerry
22
None
他在吃 <__main__.Person object at 0x0000000002312070>
jerry
22
None
类方法中拿不到外界的实例,所以只能访问类属性。
print(Person.run()) # 能访问到类属性name,不能实例属性age
print(p.run()) # 能访问到类属性name,不能实例属性age
返回结果:
AttributeError: type object 'Person' has no attribute 'age'
小明会跑步 <class '__main__.Person'>
jerry
静态方法中拿不到实例只能通过类直接调用类属性。
print(Person.haha()) # 能访问到类属性name,不能实例属性age
print(p.haha()) # 能访问到类属性name,不能实例属性age
返回结果:
AttributeError: type object 'Person' has no attribute 'age'