正如haraprasadj 所说,Python 不是静态类型的,因此您可能应该尝试习惯它并相应地编写代码。 Python 不是 Java。我来自 Java,我花了一段时间才习惯这种东西,但是一旦你习惯了,你会发现 Java 的语法不必要地“挑剔”和混乱(嗯……至少,我现在这样做了)
说了这么多,有了new style classes(继承自object的类),您可以使用@propertydecorator并创建透明的getter和setter(见this question、this question和this document)
在您的情况下,要强制Slot 类的element 属性始终为None 或Module 的实例,您可以执行以下操作:
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"
哪些输出:
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
好的,这里发生了什么?当您创建Slot 的实例(变量s)并尝试使用s.module = "whatever" 为其module 属性分配某些内容时,实际发生的是调用s 的@element.setter 方法,使用"whatever" 作为 e 参数。如果方法没有抛出异常,则实际属性存储在s._module中)您可以使用vars(s)检查类的实际属性(参见this关于vars):
>> s = Slot()
>> m = Module('name', 'type')
>> s.element = m
>> print "%s" % vars(s)
{'count': 1, 'id': 0, '_element': <__main__.Module object at 0x19d0b10>}
看到了吗?那里没有element,但是_element
现在,当您尝试使用s.element 读取element 属性时,正在调用以@property 装饰的方法。
在我发布的示例中,在该方法中添加 print 语句:
@property
def element(self):
print "I'm reading self._element. Wohooo"
return self._element
现在,重新执行脚本。您将在输出中看到:
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