Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
411 views
in Technique[技术] by (71.8m points)

python - @classmethod和@staticmethod对初学者的意义? [重复](Meaning of @classmethod and @staticmethod for beginner? [duplicate])

This question already has an answer here:

(这个问题在这里已有答案:)

Could someone explain to me the meaning of @classmethod and @staticmethod in python?

(有人可以向我解释@classmethod@staticmethod在python中的含义吗?)

I need to know the difference and the meaning.

(我需要知道差异和意义。)

As far as I understand, @classmethod tells a class that it's a method which should be inherited into subclasses, or... something.

(据我所知, @classmethod告诉一个类,它是一个应该继承到子类的方法,或者......某种东西。)

However, what's the point of that?

(但是,重点是什么?)

Why not just define the class method without adding @classmethod or @staticmethod or any @ definitions?

(为什么不在不添加@classmethod@staticmethod或任何@ definitions的情况下定义类方法?)

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

(tl; dr:我应该何时使用它们, 为什么要使用它们,我应该如何使用它们?)

I'm pretty advanced with C++, so using more advanced programming concepts shouldn't be a problem.

(我在C ++方面非常先进,所以使用更高级的编程概念应该不是问题。)

Feel free giving me a corresponding C++ example if possible.

(如果可能的话,请随意给我一个相应的C ++示例。)

  ask by translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.

(尽管classmethodstaticmethod非常相似,但两个实体的使用情况略有不同: classmethod必须引用类对象作为第一个参数,而staticmethod根本没有参数。)

Example (例)

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

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

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

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.

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

Class Method

(类方法)

We have some tasks that can be nicely done using classmethod s.

(我们有一些使用classmethod可以很好地完成的任务。)

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

(假设我们想要创建许多Date类实例,其日期信息来自外部源,编码为格式为'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. Parse a string to receive day, month and year as three integer variables or a 3-item tuple consisting of that variable.

    (解析字符串以接收日,月和年作为三个整数变量或由该变量组成的3项元组。)

  2. Instantiate Date by passing those values to the initialization call.

    (通过将这些值传递给初始化调用来实例化Date 。)

This will look like:

(这看起来像:)

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

For this purpose, C++ can implement such a feature with overloading, but Python lacks this overloading.

(为此,C ++可以通过重载实现这样的功能,但是Python缺少这种重载。)

Instead, we can use classmethod .

(相反,我们可以使用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. 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).

    (封装在这里工作正常(如果你认为你可以在其他地方实现字符串解析作为单个函数,这个解决方案更适合OOP范例)。)

  3. cls is an object that holds the class itself , not an instance of the class.

    (cls是一个保存类本身的对象,而不是的实例。)

    It's pretty cool because if we inherit our Date class, all children will have from_string defined also.

    (这很酷,因为如果我们继承Date类,所有子from_string定义from_string 。)

Static method

(静态方法)

What about staticmethod ?

(staticmethod怎么样?)

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

(它与classmethod非常相似,但不采用任何强制参数(如类方法或实例方法)。)

Let's look at the next use case.

(我们来看看下一个用例。)

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.

(此任务在逻辑上也绑定到我们目前使用的Date类,但不需要实例化它。)

Here is where staticmethod can be useful.

(这是staticmethod方法可能有用的地方。)

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

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.

(因此,正如我们从staticmethod使用中看到的那样,我们无法访问类的内容 - 它基本上只是一个函数,在语法上称为方法,但无法访问对象及其内部(字段和另一种方法),而classmethod。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...