Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在python中使用classmethod而不是实例方法_Python - Fatal编程技术网

为什么在python中使用classmethod而不是实例方法

为什么在python中使用classmethod而不是实例方法,python,Python,我已经试着了解classmethods有一段时间了。我知道它们是如何工作的,但我不明白为什么要使用它们或不使用它们 比如说 我知道我可以使用这样的实例方法: class MyClass(): def __init__(self): self.name = 'Chris' self.age = 27 def who_are_you(self): print('Hello {}, you are {} years old'.forma

我已经试着了解classmethods有一段时间了。我知道它们是如何工作的,但我不明白为什么要使用它们或不使用它们

比如说

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

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

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

在你的第二个例子中,你已经将名字和年龄硬编码到了类中。如果名称和年龄确实是类的属性,而不是类的特定实例,则使用类方法是有意义的。但是,如果您的类类似于
Human
,其中有许多具有不同名称和年龄的实例,则不可能创建类方法来访问特定实例的唯一名称和年龄。在这种情况下,您可能希望使用实例方法

一般而言:

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

@classmethod声明该方法是静态的,因此您可以在不创建类的新实例的情况下使用它。另一方面,在第一个示例中,您必须先创建实例,然后才能使用该方法。 静态方法对于MVC模式等中的控制器非常有用,而非静态方法用于模型中。 更多关于@classmethod和@staticmethod的信息,请点击此处
当您没有、不需要或无法拥有实例时,将调用类方法。有时,当以这种方式使用时,类可以充当单例。但类方法最常用的用法可能是作为非标准构造函数

例如,Python
dict
类有一个名为
dict.fromkeys(
seq,[value]
的非标准构造函数。显然,不可能涉及任何实例——关键是创建一个实例。但它不是标准的
\uuuu init\uuu()
构造函数,因为它以稍微不同的格式获取数据

标准库中有类似的方法:
int.from_bytes
bytes.fromhex
bytearray.fromhex()
float.fromhex()


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

当你有实例变量时,你会使用实例方法。使用class方法,您不能有具有不同年龄或名称的不同实例:您通常不会创建一个类来表示一个人。通常,您创建一个类
Person
,并创建它的实例来表示Person。可能的重复项以及Ginger所说的,您将Chris和27传递到Person类的构造函数中,不要硬编码到classI中我已经看过很多classmethod的例子,你的解释是第一个对我有意义的。非常感谢。