@classmethod和@staticmethod对初学者的意义? [英] Meaning of @classmethod and @staticmethod for beginner?

查看:235
本文介绍了@classmethod和@staticmethod对初学者的意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以向我解释python中@classmethod@staticmethod的含义吗?我需要知道区别和含义.

Could someone explain to me the meaning of @classmethod and @staticmethod in python? I need to know the difference and the meaning.

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

As far as I understand, @classmethod tells a class that it's a method which should be inherited into subclasses, or... something. However, what's the point of that? Why not just define the class method without adding @classmethod or @staticmethod or any @ definitions?

tl; dr: 何时应使用它们,为什么应使用它们,如何我用它们吗?

tl;dr: when should I use them, why should I use them, and how should I use them?

推荐答案

尽管classmethodstaticmethod非常相似,但两个实体在用法上都有细微差别:classmethod必须具有对类对象的引用作为第一个参数,而staticmethod完全没有参数.

Though classmethod and staticmethod are quite similar, there's a slight difference in usage for both entities: classmethod must have a reference to a class object as the first parameter, whereas staticmethod can have no parameters at all.

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')

说明

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

Explanation

Let's assume an example of a class, dealing with date information (this will be our boilerplate):

class Date(object):

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

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

This class obviously could be used to store information about certain dates (without timezone information; let's assume all dates are presented in UTC).

这里有__init__,它是Python类实例的典型初始化程序,它以典型的instancemethod形式接收参数,并具有第一个非可选参数(self),该参数保存对新创建的实例的引用.

Here we have __init__, a typical initializer of Python class instances, which receives arguments as a typical instancemethod, having the first non-optional argument (self) that holds a reference to a newly created instance.

类方法

我们有一些任务可以使用classmethod s很好地完成.

We have some tasks that can be nicely done using classmethods.

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

Let's assume that we want to create a lot of Date class instances having date information coming from an outer source encoded as a string with format 'dd-mm-yyyy'. Suppose we have to do this in different places in the source code of our project.

所以我们在这里要做的是:

So what we must do here is:

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

这看起来像:

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

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

For this purpose, C++ can implement such a feature with overloading, but Python lacks this overloading. Instead, we can use classmethod. Let's create another "constructor".

    @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')

让我们更仔细地看一下上述实现,并回顾一下我们在这里有哪些优势:

Let's look more carefully at the above implementation, and review what advantages we have here:

  1. 我们已经在一个地方实现了日期字符串解析,现在可以重用了.
  2. 封装在这里可以很好地工作(如果您认为可以在其他地方将字符串解析作为单个函数实现,则此解决方案更适合OOP范式).
  3. cls是一个保存类本身的对象,而不是该类的实例.这很酷,因为如果我们继承我们的Date类,则所有子代也将定义from_string.
  1. We've implemented date string parsing in one place and it's reusable now.
  2. Encapsulation works fine here (if you think that you could implement string parsing as a single function elsewhere, this solution fits the OOP paradigm far better).
  3. cls is an object that holds the class itself, not an instance of the class. It's pretty cool because if we inherit our Date class, all children will have from_string defined also.

静态方法

staticmethod怎么样?它与classmethod非常相似,但不使用任何强制性参数(就像类方法或实例方法一样).

What about staticmethod? It's pretty similar to classmethod but doesn't take any obligatory parameters (like a class method or instance method does).

让我们看看下一个用例.

Let's look at the next use case.

我们有一个日期字符串,我们希望以某种方式对其进行验证.从逻辑上讲,此任务也已绑定到我们到目前为止使用的Date类,但不需要实例化.

We have a date string that we want to validate somehow. This task is also logically bound to the Date class we've used so far, but doesn't require instantiation of it.

在这里staticmethod可能有用.让我们看下一段代码:

Here is where staticmethod can be useful. Let's look at the next piece of code:

    @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则是内部结构.

So, as we can see from usage of staticmethod, we don't have any access to what the class is---it's basically just a function, called syntactically like a method, but without access to the object and its internals (fields and another methods), while classmethod does.

这篇关于@classmethod和@staticmethod对初学者的意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆