Python中的类并定义属性的类型

2024-03-28 10:37:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python新手,对python2.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元素的列表


Tags: selfnodeifinitdeftypelistclass
3条回答

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

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

编写getter和setter方法也非常简单,特别是当它们只返回属性时。调用代码应该直接访问属性

至于您的问题,因为您使用的是Python2[*],所以您的类必须从对象继承。如果这样做,您将看到正确的类型:

class Graph(object):
   ...

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

(*)注意,您确实不能使用2.6;它已过时且不受支持。如果你被卡在2.x上,至少使用2.7;但是你真的应该使用3.x,它除了修复了你原来的问题之外

如果您使用的是最新版本的Python(在编写本文时是3.6.0),那么确实有

from typing import List

class Graph:
    nodeList: List[Node]

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

对于旧版本的Python3,您可以使用格式注释执行类似操作,然后typechecking工具将能够执行相同的检查:

from typing import List

class Graph:
    nodeList  # type: List[Node]

当然,所有这些在运行程序之前只提供可选的静态类型检查。一旦代码运行,只要对象具有正确的方法和属性,Python就不会关心对象的类型:如果它像鸭子一样嘎嘎作响,Python会把它当作鸭子对待

如果您想了解更多关于Python中可选静态类型检查的信息,请参见http://mypy-lang.org/

打印Node类型的实例会给您<type 'instance'>这一事实表明您使用的是Python 2的某个版本。如果可能,请考虑切换到较新的版本,但如果您想继续使用Python 2,至少要确保所有对象显式派生自object

class Node(object):
   ...

如果这样做,print语句将显示类。如果做不到这一点,就会得到Python早期的老式类,您会发现属性之类的东西不能正确使用它们

无法在Python中强制类型,因为Python是动态类型化的

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

首先,从object(即“new style”对象)继承类:

class Node(object):
   # your code here

class Graph(object):
   # your code here

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

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

相关问题 更多 >