Python中的类属性

Python中的类属性,python,class-attribute,Python,Class Attribute,以下两段代码有什么不同吗?如果不是,一个是否优于另一个?为什么允许我们动态创建类属性 片段1 class Test(object): def setClassAttribute(self): Test.classAttribute = "Class Attribute" Test().setClassAttribute() 片段2 class Test(object): classAttribute = "Class Attribute" Test() 我

以下两段代码有什么不同吗?如果不是,一个是否优于另一个?为什么允许我们动态创建类属性

片段1

class Test(object):
    def setClassAttribute(self):
        Test.classAttribute = "Class Attribute"

Test().setClassAttribute()
片段2

class Test(object):
    classAttribute = "Class Attribute"

Test()

我觉得#2感觉更自然#1的实现意味着在创建类的实际实例之前不会设置属性,在我看来,这与类属性(相对于对象属性)应该是什么有悖常理。

我认为#2感觉更自然#1的实现意味着在创建类的实际实例之前不会设置属性,这对我来说似乎与类属性(相对于对象属性)应该是什么背道而驰。

首先,在实例方法上设置类属性是一件奇怪的事情。忽略
self
参数并直接进行
Test
是另一件奇怪的事情,除非您特别希望所有子类共享一个值*

*如果您确实希望所有子类共享一个值,我会将其设置为无参数的
@staticmethod
(并将其设置为
Test
)。但在这种情况下,它甚至没有真正被用作类属性,而且作为一个全局模块可能会更好,可以使用一个自由函数来设置它

所以,即使你想使用第一个版本,我也会这样写:

class Test(object):
    @classmethod
    def setClassAttribute(cls):
        cls.classAttribute = "Class Attribute"

Test.setClassAttribute()

然而,尽管如此,我认为第二个更像是蟒蛇。以下是考虑因素:

  • 通常,Python中强烈反对使用getter和setter
  • 第一个类留下了一个空白,在此期间类存在,但没有属性
  • 简单总比复杂好

需要记住的一点是,Python中不需要getter和setter的部分原因是,如果以后需要对属性进行计算、验证等,则始终可以使用
@属性替换属性。使用class属性,这不是一个完美的解决方案,但通常已经足够好了



最后一件事:类属性(和类方法,除了替代构造函数)通常是更高级别上非Python设计的标志。当然,不总是这样,但经常是这样,所以有必要大声解释为什么需要类属性,并确保它是合理的。(如果你曾经用一种习惯用法广泛使用类属性的语言编写过程序,特别是在Java语言中,那就去找一个从未使用过Java的人,试着向他解释一下。)

首先,在实例方法上设置类属性是一件很奇怪的事情。忽略
self
参数并直接进行
Test
是另一件奇怪的事情,除非您特别希望所有子类共享一个值*

*如果您确实希望所有子类共享一个值,我会将其设置为无参数的
@staticmethod
(并将其设置为
Test
)。但在这种情况下,它甚至没有真正被用作类属性,而且作为一个全局模块可能会更好,可以使用一个自由函数来设置它

所以,即使你想使用第一个版本,我也会这样写:

class Test(object):
    @classmethod
    def setClassAttribute(cls):
        cls.classAttribute = "Class Attribute"

Test.setClassAttribute()

然而,尽管如此,我认为第二个更像是蟒蛇。以下是考虑因素:

  • 通常,Python中强烈反对使用getter和setter
  • 第一个类留下了一个空白,在此期间类存在,但没有属性
  • 简单总比复杂好

需要记住的一点是,Python中不需要getter和setter的部分原因是,如果以后需要对属性进行计算、验证等,则始终可以使用
@属性替换属性。使用class属性,这不是一个完美的解决方案,但通常已经足够好了



最后一件事:类属性(和类方法,除了替代构造函数)通常是更高级别上非Python设计的标志。当然,不总是这样,但经常是这样,所以有必要大声解释为什么需要类属性,并确保它是合理的。(如果你曾经用一种习惯用法广泛使用类属性的语言编写过程序,特别是在Java语言中,那就去找一个从未使用过Java的人,并试着向他解释一下。)

像#2这样做更自然,但请注意,它们做的事情不同。对于#2,类始终具有该属性。使用#1,在调用
setClassAttribute
之前,它不会具有该属性


您曾问过,“为什么允许我们动态创建类属性?”对于Python,问题通常不是“为什么允许我们创建类属性”,而是“为什么应该阻止我们创建类属性?”类与其他任何对象一样,都有属性。对象(通常)可以随时获得新属性。没有理由让类成为该规则的例外。

像#2这样做更自然,但请注意它们做的事情不同。对于#2,类始终具有该属性。使用#1,在调用
setClassAttribute
之前,它不会具有该属性


您曾问过,“为什么允许我们动态创建类属性?”对于Python,问题通常不是“为什么允许我们创建类属性”,而是“为什么应该阻止我们创建类属性?”类与其他任何对象一样,都有属性。对象(通常)可以随时获得新属性。没有理由让类成为该规则的例外。

我会使用第二个。这取决于您是否想要控制创建。如果不是,我将避免代码行和额外的函数调用。另外,
setClassAttribute
应该是一个classmethod,否则它毫无意义。我同意wenzul的观点。它们是等价的,但是,如果你忘记了,你会有一些有趣的错误