在面向对象中类的方法使用是很有讲究的,其中实例方法,类方法和静态方法的用法个有不同,存在的意义也是不一样的。本文将从一个实例出发,分别对实例方法,类方法和静态方法的进行调用,来进一步了解类的用法。
一、方法调用
首先我们先创建一个类,类中创建三个方法,同时实例化一个对象p。
class Person:
name = 'jerry'
def eat(self, food):
print('他在吃' + food, self)
@classmethod
def run(cls):
print('小明会跑步', cls)
@staticmethod
def haha():
print('小明在大笑')
p = Person()
1.实例方法
实例方法eat()的调用:直接使用对象p来调用实例方法,所以解释器会把p当做方法中的self直接传递进去,我们只要写另外的参数就可以;也可以使用类来调用内部的实例方法,但是要传入两个参数,第一个是对象,不推荐这种用法。
p = Person()
p.eat('水果') # 这里使用p来调用实例方法,所以解释器会把p当做方法中的self直接传递进去,我们只要写另外的参数就可以
print(p) # 这里的p和self的内存地址一样
Person.eat('aaa', '西瓜') # 也可以使用类来调用内部的实例方法,但是要传入两个参数,第一个是对象,不推荐
返回结果:
他在吃水果 <__main__.Person object at 0x0000000001E82070>
<__main__.Person object at 0x0000000001E82070>
他在吃西瓜 aaa
结论:实例方法的使用我们可以使用对象直接调用,也可以使用类直接调用。
2.类方法
类方法的调用也和上面一样,分别使用类名和实例对象来调用。
class Person:
name = 'jerry'
def eat(self, food):
print('他在吃' + food, self)
@classmethod
def run(cls):
print('小明会跑步', cls)
@staticmethod
def haha():
print('小明在大笑')
# 1.实例方法
p = Person()
Person.run()
p.run() # 这里是把实例忽略,但是向上溯源到实例所在的类,并把类作为参数穿个cls
返回结果:
小明会跑步 <class '__main__.Person'>
小明会跑步 <class '__main__.Person'>
注意:如果使用子类来调用类方法,则会把子类传递给cls,后面继承中详解
3.静态方法
class Person:
name = 'jerry'
def eat(self, food):
print('他在吃' + food, self)
@classmethod
def run(cls):
print('小明会跑步', cls)
@staticmethod
def haha():
print('小明在大笑')
# 1.实例方法
p = Person()
Person.haha() # 使用类调用静态方法
p.haha() # 使用实例调用静态方法
返回结果:
小明在大笑
小明在大笑
二、实例方法、类方法和静态方法访问类属性和实例属性
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 # 增加一个实例属性
1.访问实例属性
通过三个方法来访问实例属性age和类属性name,实例属性通过self可以拿到实例对象,所以实例属性和类属性都能通过self访问到。
print(Person.eat(p)) # 能访问到实例属性age和类属性name
print(p.eat()) # 能访问到实例属性age和类属性name
返回结果:
他在吃 <__main__.Person object at 0x0000000002322070>
jerry
22
None
他在吃 <__main__.Person object at 0x0000000002322070>
jerry
22
None
2.访问类属性
print(Person.run()) # 能访问到类属性name,不能实例属性age
print(p.run()) # 能访问到类属性name,不能实例属性age
返回结果:
AttributeError: type object 'Person' has no attribute 'age'
小明会跑步 <class '__main__.Person'>
jerry
从结果可以看出来,使用类方法无法访问实例属性。
3.静态方法使用属性
print(Person.haha()) # 能访问到类属性name,不能实例属性age
print(p.haha()) # 能访问到类属性name,不能实例属性age
返回结果:
AttributeError: type object 'Person' has no attribute 'age'
小明在大笑
jerry