0

下面两段代码有什么区别吗?如果不是,一个比另一个更受欢迎吗?为什么我们可以动态创建类属性?

片段 1

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

Test().setClassAttribute()

片段 2

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

Test()
4

3 回答 3

5

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

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

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

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

Test.setClassAttribute()

然而,话虽如此,我认为第二个更像pythonic。以下是考虑因素:

  • 一般来说,Python 中强烈建议不要使用 getter 和 setter。
  • 第一个留下了类存在但没有属性的间隙。
  • 简单胜于复杂。

要记住的一件事是,在 Python 中不需要 getter 和 setter 的部分原因是,@property如果您以后需要计算、验证等属性,您总是可以用 a 替换属性。对于类属性,这不是相当完美的解决方案——但它通常已经足够好了。


最后一件事:类属性(和类方法,除了替代构造函数)通常是更高级别的非 Python 设计的标志。当然,并非总是如此,但经常有必要大声解释为什么你认为你需要一个类属性并确保它有意义。(如果你曾经用一种语言编程,其习惯用法广泛使用类属性——尤其是 Java 的话——去找一个从未使用过 Java 的人,并尝试向他解释。)

于 2014-12-02T19:35:53.163 回答
1

像#2那样做更自然,但请注意他们做不同的事情。使用#2,该类始终具有该属性。使用 #1,在您调用setClassAttribute.

你问,“为什么我们可以动态创建类属性?” 对于 Python,问题通常不是“为什么我们会被允许”,而是“为什么我们应该被阻止?” 类和其他对象一样是一个对象,它具有属性。对象(通常)可以随时获得新属性。没有理由让课程成为该规则的例外。

于 2014-12-02T21:00:19.530 回答
0

我认为#2感觉更自然。#1 的实现意味着在创建类的实际实例之前不会设置属性,在我看来,这与类属性(与对象属性)应该是什么是违反直觉的。

于 2014-12-02T19:33:09.567 回答