As haraprasadj says, Python is not statically typed so you should probably try to get used to that and code accordingly. Python is NOT Java. I came from Java, and it took me a while getting used to this kind of stuff, but once you do, you'll find Java's syntax unnecessarily "picky" and cluttered (well... at least, I do now)
All this said, with new style classes (classes inheriting from object
) you can use the @property
decorator and create transparent getters and setters (see this question, this question and this document)
In your case, to enforce that the element
attribute of the Slot
class is always None
or an instance of Module
, you can do the following:
class Module(object):
count = 0
def __init__(self, m_name, m_type, m_on=False):
self.name = m_name
self.type = m_type
self.on = m_on
self.id = self.count
self.count += 1
class Slot(object):
count = 0
def __init__(self):
self.id = self.count
self.count += 1
self.element = None
@property
def element(self):
return self._element
@element.setter
def element(self, e):
if not(e is None or isinstance(e, Module)):
raise TypeError("Element must be None or Module")
self._element = e
if __name__ == "__main__":
s = Slot()
m = Module('name', 'type')
print "s.element? %s" % s.element
s.element = m
print "s.element? %s" % s.element
# Now, exception:
s.element = "hellouuuu"
Which outputs:
s.element? None
s.element? <__main__.Module object at 0x26c9b10>
Traceback (most recent call last):
File "./stack13.py", line 35, in <module>
s.element = "hellouuuu"
File "./stack13.py", line 25, in element
raise TypeError("Element must be None or Module")
TypeError: Element must be None or Module
Ok, what's happening here? When you create an instance of Slot
(variable s
) and you try to assign something to its module
attribute using s.module = "whatever"
, what's actually happening is that the @element.setter
method of s
is called, with "whatever"
as the e
parameter. If the method doesn't throw an exception, the actual attribute is stored in s._module
) You can examine the actual attributes of the class using vars(s)
(see this about vars
):
>> s = Slot()
>> m = Module('name', 'type')
>> s.element = m
>> print "%s" % vars(s)
{'count': 1, 'id': 0, '_element': <__main__.Module object at 0x19d0b10>}
See? Thre's no element
there, but _element
Now, when you try to read the element
attribute, using s.element
, what's happening is that the method decorated with @property
is being called.
In the example I posted, add a print
statement in that method:
@property
def element(self):
print "I'm reading self._element. Wohooo"
return self._element
Now, re-execute the script. You'll see this in the output:
I'm reading self._element. Wohooo
s.element? None
I'm reading self._element. Wohooo
s.element? <__main__.Module object at 0x1fd0ad0>
{'count': 1, 'id': 0, '_element': <__main__.Module object at 0x1fd0ad0>}
Traceback (most recent call last):
File "./stack13.py", line 37, in <module>
s.element = "hellouuuu"
File "./stack13.py", line 26, in element
raise TypeError("Element must be None or Module")
TypeError: Element must be None or Module