Python @classmethod
@classmethod:
定义操作类,而不是操作实例的方法。classmethod改变了调用方法的方式,因此类方法的第一个参数是类本身,而不是实例。@classmethod最常见的用途是定义备选构造方法。
1.定义方式
Python中3种方式定义类方法, 常规方式, @classmethod修饰方式, @staticmethod修饰方式
-
普通的self类方法foo()需要通过self参数隐式的传递当前类对象的实例;
-
@classmethod修饰的方法class_foo()需要通过cls参数传递当前类对象;
-
@staticmethod修饰的方法定义与普通函数是一样的。
self和cls的区别不是强制的,只是PEP8中一种编程风格,self通常用作实例方法的第一参数,cls通常用作类方法的第一参数。即通常用self来传递当前类对象的实例,cls传递当前类对象。
2. @classmethod 特点
- 声明一个类方法
- 第一个参数必须是
cls
, 它可以访问类的属性 - 类的方法只能访问类的属性,不能访问实例属性
- 类的方法可以通过
ClassName.MethodName()
访问也可以通过实例来访问。 - 它可以返回一个类的实例
例子:
class Student:
name = 'unknown' # class attribute
def __init__(self):
self.age = 20 # instance attribute
@classmethod
def tostring(cls):
print('Student Class Attributes: name=',cls.name)
类方法访问实例属性时,会报错
class Student:
name = 'unknown' # class attribute
def __init__(self):
self.age = 20 # instance attribute
@classmethod
def tostring(cls):
print('Student Class Attributes: name=',cls.name,', age=', cls.age)
>>> Student.tostring()
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
Student.tostring()
File "<pyshell#21>", line 7, in display
print('Student Class Attributes: name=',cls.name,', age=', cls.age)
AttributeError: type object 'Student' has no attribute 'age'
例子
from datetime import date
# random Person
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@staticmethod
def fromFathersAge(name, fatherAge, fatherPersonAgeDiff):
return Person(name, date.today().year - fatherAge + fatherPersonAgeDiff)
@classmethod
def fromBirthYear(cls, name, birthYear):
return cls(name, date.today().year - birthYear)
def display(self):
print(self.name + "'s age is: " + str(self.age))
class Man(Person):
sex = 'Male'
man = Man.fromBirthYear('John', 1985)
print(isinstance(man, Man))
man1 = Man.fromFathersAge('John', 1965, 20)
print(isinstance(man1, Man))
3. @classmethod 和 @staticmethod
@classmethod | @staticmethod |
---|---|
声明一个类的方法 | 声明一个静态方法 |
可以访问类的属性,不可以访问实例属性 | 既不可以访问类属性,也不可以访问实例属性 |
可以使用 ClassName.MethodName() 调用或者 object.MethodName() .调用 |
可以使用 ClassName.MethodName() 调用后者object.MethodName() .调用 |
可以声明一个类的工厂方法,返回一个实例 | 不可以返回一个实例 |
参考:
https://www.programiz.com/python-programming/methods/built-in/classmethod
https://www.tutorialsteacher.com/python/classmethod-decorator
不要小瞧女程序员
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
2019-07-20 19. slot插槽传递模板
2019-07-20 18. VUE created 方法作用
2019-07-20 17. Vue2.4+新增属性$listeners
2019-07-20 16. Vue2.4+新增属性$attrs
2019-07-20 1. HTML <fieldset> 标签
2019-07-20 15. Vue2.4+新增属性.sync
2019-07-20 14. VUE 子组件修改父组件的值