I'm tempted to define my Python classes like this:
class MyClass(object):
"""my docstring"""
msg = None
a_variable = None
some_dict = {}
def __init__(self, msg):
self.msg = msg
Is declaring the object variables (msg, a_variable, etc) at the top, like Java good or bad or indifferent? I know it's unnecessary, but still tempting to do.
Defining variables in the class defintion like that makes the variable accessible between every instance of that class. In Java terms it is a bit like making the variable static. However, there are major differences as show below.
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
As seen from the above code, it is not quite the same thing, as while the variable can be access via self.msg
, when it is assigned a value it is not assigned to the variable defined at class scope.
One of the disadvantage of doing it via the method you do is that it can lead to errors as it adds hidden state the the class. Say someone left out self.msg = "ABC"
from the constructor (Or more realistically code was refactored and only one of the definitions was altered)
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
Far better to avoid defining msg at the class level and then you avoid the issues:
class MyClass(object):
pass
print MyClass.msg #AttributeError: type object 'MyClass' has no attribute 'msg'
Declaring variables directly inside the class definition makes them class variables instead of instance variables. Class variables are somewhat similar to static variables in Java and should be used like MyClass.a_variable
. But they can also be used like self.a_variable
, which is a problem because naive programmers can treat them as instance variables. Your "some_dict" variable, for example, would be shared by each instance of MyClass
, so if you add a key "k" to it, that will be visible to any instance.
If you always remember to re-assign class variables, there's almost no difference to instance variables. Only the initial definition in MyClass
will remain. But anyway, that's not good practice as you might run into trouble when not re-assigning those variables!
Better write the class like so:
class MyClass(object):
"""
Some class
"""
def __init__(self, msg):
self.__msg = msg
self.__a_variable = None
self.__some_dict = {}
Using two underscores for "private" variables (pseudo-private!) is optional. If the variables should be public, just keep their names without the __
prefix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With