gpt4 book ai didi

python - @classmethod 和 @staticmethod 对初学者的意义

转载 作者:bug小助手 更新时间:2023-10-28 01:28:32 26 4
gpt4 key购买 nike

@classmethod@staticmethod 在 Python 中是什么意思,它们有何不同? 什么时候我应该使用它们,为什么我应该使用它们,我应该如何使用它们?

据我了解,@classmethod 告诉一个类它是一个应该被继承到子类中的方法,或者......什么。然而,这有什么意义呢?为什么不直接定义类方法而不添加 @classmethod@staticmethod 或任何 @ 定义?

最佳答案

虽然 classmethodstaticmethod 非常相似,但两个实体的用法略有不同:classmethod 必须引用一个类object 作为第一个参数,而 staticmethod 可以根本没有参数。

示例

class Date(object):

def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year

@classmethod
def from_string(cls, date_as_string):
day, month, year = map(int, date_as_string.split('-'))
date1 = cls(day, month, year)
return date1

@staticmethod
def is_date_valid(date_as_string):
day, month, year = map(int, date_as_string.split('-'))
return day <= 31 and month <= 12 and year <= 3999

date2 = Date.from_string('11-09-2012')
is_date = Date.is_date_valid('11-09-2012')

说明

让我们假设一个类的例子,处理日期信息(这将是我们的样板):

class Date(object):

def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year

这个类显然可用于存储有关某些日期的信息(没有时区信息;假设所有日期都以 UTC 表示)。

这里我们有 __init__,一个典型的 Python 类实例初始化器,它接收参数作为典型的实例方法,具有第一个非可选参数 (self)持有对新创建实例的引用。

类方法

我们有一些任务可以使用 classmethods 很好地完成。

假设我们要创建许多 Date 类实例,这些实例的日期信息来自外部源,编码为格式为“dd-mm-yyyy”的字符串。假设我们必须在项目源代码的不同位置执行此操作。

所以我们必须在这里做的是:

  1. 解析一个字符串,将日、月和年接收为三个整数变量或由该变量组成的 3 项元组。
  2. 通过将这些值传递给初始化调用来实例化 Date

这看起来像:

day, month, year = map(int, string_date.split('-'))
date1 = Date(day, month, year)

为此,C++ 可以通过重载实现这样的功能,但 Python 缺少这种重载。相反,我们可以使用 classmethod。让我们创建另一个构造函数

    @classmethod
def from_string(cls, date_as_string):
day, month, year = map(int, date_as_string.split('-'))
date1 = cls(day, month, year)
return date1

date2 = Date.from_string('11-09-2012')

让我们更仔细地看一下上面的实现,并回顾一下我们在这里有什么优势:

  1. 我们在一处实现了日期字符串解析,现在可以重复使用了。
  2. 封装在这里工作得很好(如果您认为可以在其他地方将字符串解析实现为单个函数,那么此解决方案更适合 OOP 范式)。
  3. cls类本身,而不是类的实例。这很酷,因为如果我们继承我们的 Date 类,所有的 child 也将定义 from_string

静态方法

静态方法呢?它与 classmethod 非常相似,但不带任何强制性参数(就像类方法或实例方法一样)。

让我们看看下一个用例。

我们有一个想要以某种方式验证的日期字符串。该任务在逻辑上也绑定(bind)到我们目前使用的 Date 类,但不需要对其进行实例化。

这就是 staticmethod 可能有用的地方。我们来看下一段代码:

    @staticmethod
def is_date_valid(date_as_string):
day, month, year = map(int, date_as_string.split('-'))
return day <= 31 and month <= 12 and year <= 3999

# usage:
is_date = Date.is_date_valid('11-09-2012')

所以,从 staticmethod 的用法可以看出,我们无法访问类是什么——它基本上只是一个函数,在语法上像方法一样调用,但没有访问对象及其内部结构(字段和其他方法),classmethod 确实拥有。

关于python - @classmethod 和 @staticmethod 对初学者的意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12179271/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com