python 的方法和函数,基本上函数等同于方法。
python 的类方法分三种:
- 实例方法,属于具体实例对象
- 类方法,该类对象,及该类实例对象可调用的,使用 @classmethod 装饰器
- 静态方法,直接调用,使用 @staticmethod 装饰器
类与实例
类是模板,可用于定义具体对象的属性;
实例,使用个类的具体对象,具备自己特定的属性值。
实例方法、类方法、静态方法
my_method.py 文件
# coding=utf-8
class My_class(object):
"""测试python 的 实例方法、类方法、静态方法"""
def instance_method(self, age=None):
"""
实例方法
第一个参数是实例对象,一般使用 self 代替
调用的时候需要实例化一个对象,然后使用
"""
# pass
print("我是实例方法", id(self))
@classmethod
def class_method(cls, age=None):
"""
类方法
第一个参数是类对象,使用 cls 代替
调用的时候可以使用类对象,也可以是类对象的实例
:param age:
:return:
"""
# pass
print("我是类方法", id(cls))
@staticmethod
def static_method(age=None):
"""
静态方法
可以没有参数
调用可以是类对象,也可以是类对象的实例
:param age:
:return:
"""
# pass
print("我是静态方法", id(My_class))
def main():
# 类对象直接调用方法
My_class.class_method(20)
My_class.instance_method(21)
My_class.static_method(22)
print("==" * 30)
# 实例化对象
my_class = My_class()
# 实例化对象,调用方法
my_class.class_method()
my_class.instance_method()
my_class.static_method()
if __name__ == "__main__":
print("---" * 20)
# pass
main()
class My_Class_2(object):
"""第二测试方法的类"""
def instance_method(self, age=None):
print("instance_method")
@classmethod
def class_method(cls, age=None):
print("class_method")
@staticmethod
def static_method(age=None):
print("static_method")
class My_Class_3(object):
"""第二测试方法的类"""
def instance_method(self, age=None):
print("3 instance_method")
@classmethod
def class_method(cls, age=None):
print("3 class_method")
@staticmethod
def static_method(age=None):
print("3 static_method")
class My_Class_4(object):
"""测试python 的 实例方法、类方法、静态方法"""
def instance_method(self, age=None):
"""
实例方法
第一个参数是实例对象,一般使用 self 代替
调用的时候需要实例化一个对象,然后使用
"""
# pass
print("C4 我是实例方法", id(self))
@classmethod
def class_method(cls, age=None):
"""
类方法
第一个参数是类对象,使用 cls 代替
调用的时候可以使用类对象,也可以是类对象的实例
:param age:
:return:
"""
# pass
print("4 我是类方法", id(cls))
@staticmethod
def static_method(age=None):
"""
静态方法
可以没有参数
调用可以是类对象,也可以是类对象的实例
:param age:
:return:
"""
# pass
print("4 我是静态方法", id(My_class))
test_method.py 文件
# coding=utf-8
import time
import my_method
if __name__ == "__main__":
# my_method.main()
print("=="*30)
print("=="*30)
# 类对象直接调用方法
my_method.My_class.class_method(20)
my_method.My_class.instance_method(21)
my_method.My_class.static_method(22)
print("==" * 30)
# # 实例化对象
my_class = my_method.My_class()
# 实例化对象,调用方法
my_class.class_method()
my_class.instance_method()
my_class.static_method()
print("--"*30)
print("--"*30)
my_method.My_Class_2.static_method()
my_method.My_Class_2.class_method()
# my_method.My_Class_2.instance_method()
# my_method.My_Class_2
print("--"*30)
print("--"*30)
my_method.My_Class_3.static_method()
my_method.My_Class_3.class_method()
# my_method.My_Class_3.instance_method()
# my_method.My_Class_3
print("--" * 30)
print("--" * 30)
my_method.My_Class_4.static_method()
my_method.My_Class_4.class_method()
# my_method.My_Class_4.instance_method()
# my_method.My_Class_4
time.sleep(1)
my_method.My_class.instance_method()
运行 tet_method.py 结果:
D:\devTools\Python\Miniconda3\envs\python38\python.exe D:/OtherProjects/action/practice-demo-python/py_38/drf_demo/drf_demo/test_method.py
============================================================
============================================================
我是类方法 2140269657328
我是实例方法 140708077379968
我是静态方法 2140269657328
============================================================
我是类方法 2140269657328
我是实例方法 2140301132080
我是静态方法 2140269657328
------------------------------------------------------------
------------------------------------------------------------
static_method
class_method
------------------------------------------------------------
------------------------------------------------------------
3 static_method
3 class_method
------------------------------------------------------------
------------------------------------------------------------
4 我是静态方法 2140269657328
4 我是类方法 2140269652608
Traceback (most recent call last):
File "D:/OtherProjects/action/practice-demo-python/py_38/drf_demo/drf_demo/test_method.py", line 43, in <module>
my_method.My_class.instance_method()
TypeError: instance_method() missing 1 required positional argument: 'self'
Process finished with exit code 1
令人困惑的是,前面的 my_method.My_class.instance_method() 方法可以,后面的就不可以,不应该是都不可以吗?
小结
- 定义形式上:
a. 类方法和静态方法都是通过装饰器实现的,实例方法不是;
b. 实例方法需要传入self参数,类方法需要传入cls参数,而静态方法不需要传self或者cls参数。
2. 调用方式上:
实例方法只能通过实例对象调用;类方法和静态方法可以通过类对象或者实例对象调用,如果是使用实例对象调用的类方法或静态方法,最终都会转而通过类对象调用。
3. 应用场景:
a. 实例方法使用最多,可以直接处理实例对象的逻辑;类方法不需要创建实例对象,直接处理类对象的逻辑;静态方法将与类对象相关的某些逻辑抽离出来,不仅可以用于测试,还能便于代码后期维护。
b. 实例方法和类方法,能够改变实例对象或类对象的状态,而静态方法不能。