Определение переменных в определении класса таким образом делает переменную доступной между каждым экземпляром этого класса. В терминах Java это немного похоже на , делающее переменную статической. Тем не менее, есть серьезные различия, как показано ниже.
class MyClass(object):
msg = "ABC"
print MyClass.msg #prints ABC
a = MyClass()
print a.msg #prints ABC
a.msg = "abc"
print a.msg #prints abc
print MyClass.msg #prints ABC
print a.__class__.msg #prints ABC
Как видно из приведенного выше кода, это не совсем то же самое, поскольку, хотя переменная может быть доступна через self.msg
, когда ей присваивается значение, она не присваивается переменной, определенной в области видимости класса.
Один из недостатков использования этого метода в том, что он может привести к ошибкам, так как добавляет скрытое состояние в класс. Скажем, кто-то исключил self.msg = "ABC"
из конструктора (или, более реалистично, код был подвергнут рефакторингу и изменено только одно из определений)
a = MyClass()
print a.msg #prints ABC
#somewhere else in the program
MyClass.msg = "XYZ"
#now the same bit of code leads to a different result, despite the expectation that it
#leads to the same result.
a = MyClass()
print a.msg #prints XYZ
Гораздо лучше избегать определения сообщений на уровне класса, а затем избегать проблем:
class MyClass(object):
pass
print MyClass.msg #AttributeError: type object 'MyClass' has no attribute 'msg'