Python supports class attributes, instance attributes and properties.
from time import ctime, sleep
class MyClass(object):
A = ctime() # class attribute
def __init__(self):
self.B = ctime() # instance attribute
self._C = None
@property
def C(self): # property
if self._C is None:
self._C = ctime()
return self._C
@C.setter
def C(self, c):
self._C
To a user who is not aware, how MyClass is implemented, A, B, and C show similar behaviour:
sleep(2)
myObject = MyClass()
sleep(2)
print myObject.A # prints time module was initialized
print myObject.B # prints time instance was created, 2 sec later
print myObject.C # prints time this line was called, 2 sec later
myObject.A = 'foo' # myObject.A is now an instance attribute
myObject.B = 'foo' # myObject.B is still an instance attribute
myObject.C = 'foo' # myObject.C is still an (instance) property
print myObject.A # prints 'foo'
print myObject.B # prints 'foo'
print myObject.C # prints 'foo'
From the answer I got here, I understood the following: The first time myObject.A is printed, myObject.A is myObject.__Class__.A is MyClass.A. The second time myObject.A is not myObject.__Class__.A. Fine.
In the example above, ctime() was used only to illustrate, how A, B and C differ. Now assume, we are using an immutable constant instead:
class MyClass(object):
A = 'bar' # class attribute
def __init__(self):
self.B = 'meta' # instance attribute
self._C = None
@property
def C(self): # property
if self._C is None:
self._C = 'foobar'
return self._C
@C.setter
def C(self, c):
self._C = c
myObject = MyClass()
myObject.A is still the class attribute MyClass.A, while myObject.B is an instance attribute and myObject.C is a property. All of them, do exactly what I want. They have a default value and I can assign some other value. Which style should I use, A, B or C?
The preferred way to initialize a constant class attribute is in the class definition itself.
Looking at the code in the question, it seems that there is some confusion about how to access class attributes from an instance object.
Note that in an instance object you can access class attributes by name because when an attribute isn't found in the internal dictionary, the lookup continues in the class dictionary. That is, if instance.A doesn't exist, instance.__class__.A will be return instead if it's available.
However, when an attribute is created in an object instance, the the class attribute is shadowed. That is, instance.A = <value> creates a new instance attribute and the next time you access instance.A, <value> will be returned. However, the class attribute can still be retrieved using instance.__class__.A.
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