为啥我使用@classmethod 而不是普通的实例方法[重复]

Posted

技术标签:

【中文标题】为啥我使用@classmethod 而不是普通的实例方法[重复]【英文标题】:Why am I using a @classmethod instead of a normal instance method [duplicate]为什么我使用@classmethod 而不是普通的实例方法[重复] 【发布时间】:2019-01-13 13:55:49 【问题描述】:

我观看了一个解释 @classmethods、实例方法和 @staticmethods 的 youtube 视频。我了解如何使用它们。我只是不明白何时使用它们以及为什么使用它们。这是他在 youtube 视频中为我们提供的 @classmethods 代码。

class Employee:

    # class object attributes
    num_of_emps = 0
    raise_amt = 1.04

    def __init__(self, first, last, pay):
        self.first = first
        self.last = last
        self.email = first + '.' + last + '@email.com'
        self.pay = pay

        Employee.num_of_emps += 1

    def fullname(self):
        return f'self.first self.last'

    def apply_raise(self):
        self.pay = int(self.pay * self.raise_amt)

    @classmethod
    def set_raise_amt(cls, amount):
        cls.raise_amt = amount

    @classmethod
    def from_string(cls, emp_str):
        first, last, pay = emp_str.split('-')
        return cls(first, last, pay)


emp_1 = Employee('Corey', 'Shaffer', 50000)
emp_2 = Employee('Test', 'Employee', 60000)

emp_3 = Employee.from_string('Ezekiel-Wootton-60000')
print(emp_3.email)
print(emp_3.pay)

为什么我对 from_string 方法使用@classmethod?我认为使用没有装饰器的普通实例方法更有意义,因为我们没有引用类。正确的?!?我们指的是每个将字符串作为参数传递的实例。

【问题讨论】:

这个想法是set_raise_amt 更改所有 员工的数量,而不是这个特定的员工。而from_string 在命令行中获取它需要的所有信息,因此它不需要实例。 感谢这个例子。 【参考方案1】:

from_string 的情况下,它可以用作替代构造函数。它的用法是这样的

new_employee = Employee.from_string('Corey-Shaffner-50000')

想一想,如果我想用这个方法构造我的第一个Employee,如果它是一个实例方法,我该怎么做呢?我还没有任何实例可以调用它。


set_raise_amt 的情况下,很明显您正在编辑一个类(又名静态)变量,而不是一个实例变量。话虽如此,使用 getter 和 setter 通常被认为是糟糕的 python。用户应该能够做到:

Employee.raise_amt = x

【讨论】:

以上是关于为啥我使用@classmethod 而不是普通的实例方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章

当我使用 std::algorithms 而不是普通循环时,为啥这段代码会变慢?

day25类方法classmethod静态方法staticmethod普通方法

为啥我们使用 .NET 属性而不是普通的旧 get/set 函数?

为啥parallelStream 使用ForkJoinPool,而不是普通的线程池?

Python中的classmethod与staticmethod

python 类中staticmethod,classmethod,普通方法