一、方法的概念
-
描述一个目标的行为动作: 比如描述一个人怎么吃, 怎么喝, 怎么玩
-
和函数非常相似
- 都封装了一系列动作
- 都可以被调用, 执行一系列行为动作
- 最主要的区别: 调用方式
-
定义一个函数并调用
# 定义函数
def eat():
print("吃东西")
# 调用函数
eat()
- 定义一个方法并调用
# 定义类
class Person():
# 定义方法
def eat(self):
print("吃东西")
# 创建实例
p = Person()
# 调用方法
p.eat()
二、方法的划分
方法分为实例方法、类方法和静态方法
- 实例方法: 默认第一个参数需要接受到一个实例
- 类方法: 默认第一个参数需要接收到一个类
- 静态方法: 第一个参数啥也不默认接收
注意:
- 划分的依据是: 方法的第一个参数必须要接收的数据类型
- 不管是哪一种类型的方法, 都是存储在类当中, 没有在实例当中的
- 不同类型方法的调用方式不同
class Person:
def eat(self):
print("实例方法 --- ", self)
@classmethod
def classMethod(cls):
print("类方法 --- ", cls)
@staticmethod
def staticMethod():
print("静态方法")
p = Person()
print(p) # 打印: <__main__.Person object at 0x104204748>
p.eat() # 打印: 实例方法 --- <__main__.Person object at 0x104204748>
Person.classMethod() # 打印: 类方法 --- <class '__main__.Person'>
Person.staticMethod() # 打印: 静态方法
二、实例方法
- 语法
class Person:
def 方法名(self):
pass
-
其中小括号中的是参数列表, 且必须至少有一个参数
-
参数名
self可以替换成其他参数名, 但是必须要有一个参数, 这个参数接收一个实例 -
定义一个方法
class Person:
def run(self):
print("调用实例方法 --- ", self)
1、标准调用
- 标准调用: 使用实例调用实例方法
p = Person()
p.run()
print(p)
# 打印结果:
调用实例方法 --- <__main__.Person object at 0x10341f6d8>
<__main__.Person object at 0x10341f6d8>
- 可以发现方法中打印的参数
self与调用者p是同一个实例
当使用实例调用实例方法时, 第一个参数不需要传递, 系统默认传递调用者本身
- 定义方法时, 也可以传入其他的参数
class Person:
def eat(self, food):
print(self, "-- 吃 --", food)
p = Person()
p.eat("面包")
# 打印结果:
<__main__.Person object at 0x104c1f6d8> -- 吃 -- 面包
- 实际上实例方法的第一个参数, 可以用任何名称, 而不是限制为
self,self只不过是系统推荐我们使用的参数名
class Person:
def eat(xxx, food):
print(xxx, "-- 吃 --", food)
p = Person()
p.eat("面包")
# 打印结果:
<__main__.Person object at 0x104304668> -- 吃 -- 面包
- 可以发现将参数名
self改为xxx后, 程序依然可以正常运行
实例方法总结:
- 使用实例调用实例方法, 是实例方法的标准调用方式
- 实例方法必须至少有一个参数, 这个参数需要传入一个实例, 当使用实例调用方法时, 系统默认传入该实例
- 实例方法的第一个参数的参数名
self, 是系统推荐我们使用的, 而不是固定的, 我们可以将其更改成任何名称
2、其他调用
类名调用实例方法: 第一个参数, 必须手动传入一个实例, 如果调用时什么都不传会报错
class Person:
def eat(self):
print("吃东西", self)
Person.eat("xxx")
# 打印结果:
吃东西 xxx
# 如果不传参数, 会报错
Person.eat()
# 报错: TypeError: eat() missing 1 required positional argument: 'self'
间接调用: 将方法赋值给一个变量, 通过变量调用方法, 必须手动传入一个实例
eat = Person.eat
eat("xxx")
# 打印结果:
吃东西 xxx
三、类方法
-
类方法, 是一个需要使用装饰器
classmethod装饰的方法 -
语法
@classmethod
def 类名(cls, arg1, arg2...):
pass
- 举例
class Person:
@classmethod
def leifangfa(cls):
print("类方法 -- ", cls)
1、类名调用类方法
- 使用类名调用类方法时, 第一个参数不需要传递, 系统默认传入该类
Person.leifangfa()
# 打印结果:
类方法 -- <class '__main__.Person'>
2、实例调用
- 使用实例调用类方法时, 第一个参数不需要传递, 系统默认使用实例的
__class__所指定的类名
p = Person()
p.leifangfa()
# 打印结果:
类方法 -- <class '__main__.Person'>
3、间接调用
- 间接调用: 是指将类方法赋值给一个变量, 使用变量调用类方法, 第一个参数不用传递, 会自动传入该类
func = Person.leifangfa
func()
# 打印结果:
类方法 -- <class '__main__.Person'>
四、静态方法
-
静态方法: 没有任何必须的默认参数, 需要使用装饰器
staticmethod装饰 -
语法
@staticmethod(arg1, arg2...):
pass
- 示例
class Person:
@staticmethod
def jingtaifangfa():
print("这是一个静态方法")
1、类名调用
- 使用类名可以直接调用静态方法, 没有任何默认传递的参数
Person.jingtaifangfa()
# 打印结果:
这是一个静态方法
2、实例调用
- 使用实例可以直接调用静态方法, 没有任何默认传递的参数
p = Person()
p.jingtaifangfa()
# 打印结果:
这是一个静态方法
3、间接调用
- 可以将静态方法传递给一个变量, 然后使用变量调用
func = Person.jingtaifangfa
func()
# 打印结果:
这是一个静态方法
总结: 在设计方法时, 如果需要用到类, 就使用类方法, 如果需要用到实例, 就使用实例方法, 如果类和实例都不需要, 就使用静态方法