为啥在 python 中使用类方法而不是实例方法

Posted

技术标签:

【中文标题】为啥在 python 中使用类方法而不是实例方法【英文标题】:Why use a classmethod over an Instance method in python为什么在 python 中使用类方法而不是实例方法 【发布时间】:2016-06-11 17:18:32 【问题描述】:

一段时间以来,我一直在努力思考类方法。我知道它们是如何工作的,但我不明白为什么要使用它们或不使用它们。

例如。

我知道我可以使用这样的实例方法:

class MyClass():
    def __init__(self):
        self.name = 'Chris'
        self.age = 27

    def who_are_you(self):
        print('Hello , you are  years old'.format(self.name, self.age)

c = MyClass()
c.who_are_you()

我也知道通过使用 classmethod 我可以调用 who_are_you() 而无需创建我的类的实例:

    class MyClass():
        name = 'Chris'
        age = 27

        @classmethod
        def who_are_you(cls):
            print('Hello , you are  years old'.format(cls.name, cls.age)

MyClass.who_are_you()

我不明白为什么你会选择一种方法而不是另一种方法

【问题讨论】:

当你有实例变量时你使用实例方法。使用类方法,您不能拥有不同年龄或名称的不同实例 见:***.com/questions/12179271/… 你通常不会创建一个类来代表一个人。通常,您创建一个类Person,并创建它的实例来代表一个人。 When should I use @classmethod and when def method(self)?的可能重复 按照 Ginger 所说,你将 Chris 和 27 传入 Person 类的构造函数,而不是将它们硬编码到类中 【参考方案1】:

在第二个示例中,您已将姓名和年龄硬编码到班级中。如果 name 和 age 确实是类的属性而不是类的特定实例,那么使用类方法是有意义的。但是,如果您的类类似于Human,其中有许多具有不同名称和年龄的实例,那么就不可能创建一个类方法来访问特定实例的唯一名称和年龄。在这种情况下,您可能需要使用实例方法。

一般:

如果您想访问整个类的属性,而不是该类的特定实例的属性,请使用类方法。 如果要访问/修改与类的特定实例关联的属性,则需要使用实例方法。

【讨论】:

我一直在查看许多类方法的示例,您的解释对我来说是第一个有意义的。谢谢【参考方案2】:

@classmethod 声明该方法是静态的,因此您可以在不创建类的新实例的情况下使用它。另一方面,在第一个示例中,您必须先创建实例,然后才能使用方法。 静态方法对于 MVC 模式等的控制器非常有用,而非静态方法用于模型中。 更多关于@classmethod 和@staticmethod 的信息在这里 https://***.com/a/12179752/5564059

【讨论】:

【参考方案3】:

当您没有、不需要或不能拥有实例时,将调用类方法。有时,以这种方式使用时,一个类可以用作单例。但可能类方法最常见的用途是作为非标准构造函数。

例如,Python dict 类有一个名为 dict.fromkeys(seq, [value]) 的非标准构造函数。显然,不能涉及实例——重点是创建一个实例。但它不是标准的__init__() 构造函数,因为它采用的数据格式略有不同。

标准库中有类似的方法:int.from_bytesbytes.fromhexbytearray.fromhex()float.fromhex()

如果您考虑 Unix 标准库,fdopen 函数是一个类似的想法 - 它从描述符而不是字符串路径构造文件。 Python 的open() 将接受文件句柄而不是路径,因此它不需要单独的构造函数。但这个概念比你想象的更普遍。

【讨论】:

以上是关于为啥在 python 中使用类方法而不是实例方法的主要内容,如果未能解决你的问题,请参考以下文章

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

为啥方法局部静态变量绑定到类而不是实例?

python 为啥要使用静态方法

python 创建类和为什么类方法中self形参必不可少?

使用 Objective-C/Swift 单例模型,为啥我们要创建共享实例而不只是使用类方法? [复制]

为啥 Python 代码使用 len() 函数而不是长度方法?