Python中的类属性
以下两段代码有什么不同吗?如果不是,一个是否优于另一个?为什么允许我们动态创建类属性 片段1Python中的类属性,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() 我
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的观点。它们是等价的,但是,如果你忘记了,你会有一些有趣的错误