2014-12-02 2 views
0

Есть ли разница в следующих двух частях кода? Если нет, то предпочтительнее другого? Зачем нам позволять динамически создавать атрибуты класса?Атрибуты класса в Python

Отрывок 1

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

Test().setClassAttribute() 

Отрывок 2

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

Test() 
+1

Я бы использовал второй. Это зависит от того, хотите ли вы контролировать процесс создания или нет. Если нет, я бы избегал строк кода и дополнительного вызова функции. Также 'setClassAttribute' должен быть classmethod, иначе это бессмысленно. – wenzul

+0

Я согласен с wenzul. Они эквивалентны, но № 1, если вы забудете, у вас появятся интересные ошибки. – matsjoyce

+0

Нет смысла создавать экземпляр класса, чтобы установить атрибут класса, поэтому ни один из них не является предпочтительным. Кроме того, что такое ваше мнение по этому вопросу? –

ответ

1

Это более естественно сделать это как # 2, но заметьте, что они делают разные вещи. С # 2 класс всегда имеет атрибут. С №1 у него не будет атрибута, пока вы не вызовете setClassAttribute.

Вы спросили: «Зачем нам позволять динамически создавать атрибуты класса?» С Python часто возникает вопрос «почему нам разрешено», но «почему мы должны быть предотвращены?». Класс - это объект, как любой другой, он имеет атрибуты. Объекты (как правило) могут получать новые атрибуты в любое время. Нет причин, по которым класс должен быть исключением из этого правила.

0

Я думаю, # 2 чувствует себя более естественно. Реализация # 1 означает, что атрибут не будет установлен до тех пор, пока не будет создан фактический экземпляр класса, что для меня кажется противоречащим тому, что должно быть атрибутом класса (атрибутом объекта).

5

Во-первых, установка атрибута класса для метода экземпляра - это странная вещь. И игнорируя параметр self и ладится на Test еще одна странная вещь, чтобы сделать, если вы специально не хотите, чтобы все подклассы разделять одно значение. *

* Если вы сделал специально хочу, чтобы все подклассы разделять одно значение , Я бы сделал его @staticmethod без каких-либо параметров (и установил его на Test). Но в этом случае он даже не используется в качестве атрибута класса и может работать лучше как глобальный модуль со свободной функцией для его установки.

Таким образом, даже если вы хотите идти с первой версией, я бы написал так:

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

Test.setClassAttribute() 

Однако все сказанное, я думаю, что второй является гораздо более вещий. Ниже приводятся следующие соображения:

  • В целом, геттеры и сеттеры сильно обескуражены в Python.
  • Первый оставляет пробел, в течение которого класс существует, но не имеет атрибута.
  • Простой лучше, чем сложный.

Единственное, что нужно иметь в виду, что одна из причин, методы получения и установки являются необходимыми в Python является то, что вы всегда можете заменить атрибут с @property, если позже это нужно, чтобы быть вычислен, заверенной и т. д. С атрибутом класса это не совсем идеальное решение, но оно обычно достаточно хорошее.


последнее: атрибуты класса (и методы класса, для альтернативного конструктора, кроме) часто являются признаком, не вещий дизайн на более высоком уровне. Не всегда, конечно, но достаточно часто, что стоит объяснить вслух, почему вы считаете, что вам нужен атрибут класса и убедитесь, что это имеет смысл. (И если вы когда-либо программировали на языке, чьи идиомы широко используют атрибуты класса, особенно если это Java-go, найдите того, кто никогда не использовал Java и не пытался объяснить это ему.)

Смежные вопросы