如何在Python中创建强类型对象引用?

时间:2014-04-06 10:03:56

标签: python class object reference typing

我刚开始使用Python 2.7进行冒险。

我想从一个类到另一个类进行某种强类型引用。

假设我有两个班级:

class Module:
    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

Slot我希望将Module作为元素:

class Slot:
    count = 0

    def __init__(self):
        self.id  = self.count
        self.count += 1
        self.element = None

现在我想添加方法来设置该插槽中的element,然后在其他方法(使用它的字段和方法)中使用它,但我想确保它将是element:Module。

如果我能“告诉”PyCharm elementModule的类型,那么它将会自动完成我的输入。

甚至可能吗?我可以在其他时候欺骗python:

self.element = Module()

在init方法中(如果我在上面做,它将元素识别为Module的类型并且它会自动完成)。

2 个答案:

答案 0 :(得分:1)

正如haraprasadj所说,Python不是静态类型的,因此您可能应该尝试习惯并相应地编写代码。 Python不是Java。我来自Java,我花了一段时间习惯这种东西,但是一旦你这样做,你会发现Java的语法不必要地“挑剔”和混乱(好吧......至少,我现在这样做)

所有这些说明,new style classes(继承自object的类)您可以使用@property decorator并创建透明的 getters 和< em> setters (请参阅this questionthis questionthis document

在您的情况下,要强制element类的Slot属性始终为NoneModule的实例,您可以执行以下操作:

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)的实例并尝试使用module为其s.module = "whatever"属性分配内容时,实际发生的是{{1}调用@element.setter的方法,s作为"whatever"参数。如果方法没有抛出异常,则实际属性存储在e中。您可以使用s._module检查类的实际属性(请参阅this关于vars(s) ):

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阅读element属性时,正在发生的是正在调用用s.element修饰的方法。

在我发布的示例中,在该方法中添加@property语句:

print

现在,重新执行脚本。你会在输出中看到这个:

@property
def element(self):
    print "I'm reading self._element. Wohooo"
    return self._element

答案 1 :(得分:0)

我猜你的意思是静态类型引用,而不是强类型引用。 Python引用是强类型的。

如果你想要静态类型,那么Python就没有了。

我也不认为声明中有任何诡计:

self.element = Module()

这只是创建了一个Module类的对象。还有变量&#39;元素的类型&#39;除非您对另一种类型进行显式重新分配,否则仍为Module类。

这与我们在C ++或Java中所做的不同,但在我看来,这种灵活性增加了Python的强大功能

希望这有帮助。