1. 运行环境
以下Python脚本均在Python3.9.12上运行通过。
2. 基础使用
直接以一个示例来说明:
- 使用类实例对象调用类的实例方法:首先实例化类得到其对象person,通过类对象person调用类实例方法set_name,此时打印self可以看到self表示的是Person的对象。
class Person():
name = "Tom"
def set_name(self, value):
print(self, value)
self.name = value
person = Person()
person.set_name("Mary")
print(person.name)
输出结果如下:
<__main__.Person object at 0x000001C102844F70> Mary
Mary
- 使用类本身调用类的实例方法
class Person():
name = "Tom"
def set_name(self, value):
print(self, value)
self.name = value
person = Person()
Person.set_name("Tim")
print(person.name)
输出结果:
Traceback (most recent call last):
File "F:\CODE\pytest\pytest_stu\Utils\tiaoshi.py", line 9, in <module>
Person.set_name("Tim")
TypeError: set_name() missing 1 required positional argument: 'value'
通过报错信息可以发现,这里提示缺少了一个位置参数value,但是我们实际上已经传递了一个参数"Tim"到value,但是在Python处理的时候,由于调用set_name的是类而不是类的对象,因此Python不会自动给self赋值,从而将Tim赋值给了self。如果需要正确的赋值,可以参考下面
class Person():
name = "Tom"
def set_name(self, value):
print(self, value)
self.name = value
person = Person()
Person.set_name(person, "Tim")
print(person.name)
输出结果如下
<__main__.Person object at 0x0000012C327E4F70> Tim
Tim
此时就可以看到类Person成功调用了实例方法,即手动将自己实例化的person对象传递给了self。
3. 应用场景
首先,通常情况下我们一般会实例化对象,然后通过实例化对象调用实例化方法,那么什么时候会用到使用类本身调用实例化方法。下面以一个自己在实际项目中遇到的情况来举例说明,这里对具体的应用场景进行了抽象,大概意思如下:
- 在Person类中定义了类的实例方法get_random_str
- 定义了Student类,该类继承Person类,然后在Student类中定义了一个类方法print_str,但是在这个类方法中必须调用被继承类的实例方法,由于在类方法自动将类本身绑定到cls,此时如果想调用被继承类的实例方法时,此时就可以使用前面提到的方式了。
class Person():
def get_random_str(self):
return "abcd"
class Student(Person):
@classmethod
def print_str(cls):
ran_str = cls.get_random_str(Person())
print(ran_str)
Student.print_str()
4. 思考
- 是否有其他更优的方式?比如在Person中直接将get_random_str定义为类方法?那么此时就要考虑将该方法定义为类方法是否合适?什么时候将方法定义为类方法、什么时候将方法定义为实例方法、或者定义为静态方法,建议结合自己实际项目来定义或者简单参考下面两条:
1. 如果用不到类的变量,就可以考虑定义为静态方法。因为静态方法不需要使用类中的变量,也无法调用类的任何属性和方法的,仅仅因为逻辑上的需要被归并到该类中。
2. 如果用不到实例的变量,就可以考虑使用类方法。静态方法与类绑定,不与实例绑定,主要用于修改类的数据和行为。