繁体   English   中英

Python中的类并定义属性类型

[英]Classes in Python and defining the Type of Attributes

我是Python的新手,并且对Python 2.6中的类及其属性有疑问。

可以说我有一个这样的类Node

class Node:
    x = int
    y = int
    neighbours = []
    discovered = bool
    def __init__(self,x,y):
        self.x = x
        self.y = y

    def setNeigbours(self,neighbours):
        self.neighbours = neighbours

    def addNeighbours(self,n):
        if type(n) == list:
            self.neighbours.extend(n)
        else:
            self.neighbours.append(n)

    def isDiscovered(self):
        return self.discovered

    def setDiscovered(self,discovered):
        self.discovered = discovered

像这样的类Graph

class Graph:
    nodeList = Node
    edgeList = Edge

    def __init__(self,nodeList,edgeList):
        self.edgeList = edgeList
        self.nodeList = nodeList

    def getNodes(self):
        return self.nodeList

    def setNodes(self,nodeList):
        self.nodeList = nodeList

    def addNode(self,n):
        if type(n) == list:
            self.nodeList.extend(n)
        else:
            self.nodeList.append(n)

如果我现在创建一个新的图并添加一些节点:

n1 = Node(0,0)
n2 = Node(1,1)
g = Graph([],[])
g.addNode(n1)
g.addNode(n2)

我希望以下内容可以print <Type 'Node'>

for n in g.nodeList:
    print type(n)

但是当我运行它时,我得到:

<type 'instance'>
<type 'instance'>

有没有办法告诉Python, nodeList是一个仅包含Node -Elements的列表?

确实存在,只要您使用的是最新版本的Python(在撰写本文时为3.6.0)。

from typing import List

class Graph:
    nodeList: List[Node]

Python本身实际上不会对信息做任何事情,但是有一些用于Python的类型检查工具会执行静态分析,并告诉您是否尝试将Node以外的内容放入列表中。

使用旧版本的Python 3,您可以对带有注释的注释执行类似的操作,然后类型检查工具将能够执行相同的检查:

from typing import List

class Graph:
    nodeList  # type: List[Node]

当然,所有这些都仅在运行程序之前提供可选的静态类型检查。 一旦您的代码运行,Python便不会在乎对象的类型,只要它们具有正确的方法和属性即可:如果它像鸭子一样嘎嘎叫声,Python会将其视为鸭子。

如果您想进一步了解Python中的可选静态类型检查,请访问http://mypy-lang.org/

打印您的Node类型的实例会为您提供<type 'instance'>的事实,表明您正在使用某些版本的Python2。请尽可能切换到较新的版本,但至少要这样做要继续使用Python 2,请确保所有对象都明确地从object派生:

class Node(object):
   ...

如果这样做,则打印语句将向您显示课程。 未能做到这一点会使您从Python的早期开始就获得老式的类,并且您会发现诸如属性之类的东西无法正确使用它们。

这些都不是您编写Python的方式。 它看起来像Java。

您无需在类级别“声明”属性; 这样做的唯一原因是使用在所有实例之间共享的值,而您没有这样做,因为您立即用实例属性覆盖了它们。 删除这些定义。

编写getter和setter方法也很简单,尤其是当它们只是返回属性时。 您的调用代码应直接访问属性。

关于您的问题,由于您使用的是Python 2 [*],因此您的类必须从object继承。 如果这样做,您将看到正确的类型:

class Graph(object):
   ...

g = Graph()
type(g) # module.Graph

(*)注意,您实际上绝对不能使用2.6; 它已过时且不受支持。 如果卡在2.x上,请至少使用2.7;否则,请使用2.7。 但实际上您应该使用3.x,此版本可以解决您的原始问题。

由于Python是动态类型化的,因​​此无法在Python中强制执行类型。

一种可能的解决方案是在运行时检查实例类型。

首先,从object (即“新样式”对象)继承您的类:

class Node(object):
   # your code here

class Graph(object):
   # your code here

然后可以在运行时进行类型检查:

>>> g = Graph()
>>> type(g)
<class '__main__.Graph'>
>>> isinstance(g, Graph)
True

Python是动态类型的语言。 您无需在使用变量之前声明变量或声明其类型。

您可以执行以下操作:

foo = 1 # this is an integer
foo = "string" # this is a string

变量foo将具有存储在其中的值的类型。

在Python中,您可以将不同类型的对象存储在同一列表中,如果只想强制存储一种类型,则可以对内置list类进行子类化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM