我是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
- 元素?
答案 0 :(得分:1)
确实有,如果您使用的是最新版本的Python(在撰写本文时为3.6.0)。
from typing import List
class Graph:
nodeList: List[Node]
Python本身实际上不会对信息做任何事情,但是有一些Python的类型检查工具会执行静态分析并告诉您是否尝试在列表中添加Node
之外的其他内容
对于旧版本的Python 3,您可以使用fomatted注释执行类似操作,然后类型检查工具将能够执行相同的检查:
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的早期开始就会为你提供旧式的类,你会发现像属性这样的东西无法正常使用它们。
答案 1 :(得分:0)
这就是你编写Python的方式;它看起来像Java。
您不需要在班级“声明”属性;这样做的唯一原因是使用在所有实例之间共享的值,这些值您没有这样做,因为您会立即使用实例属性覆盖它们。删除这些定义。
编写getter和setter方法也非常简单,特别是如果它们只返回属性。您的调用代码应直接访问属性。
关于你的问题,因为你使用的是Python 2 [*],你的类必须从object继承。如果你这样做,你会看到正确的类型:
class Graph(object):
...
g = Graph()
type(g) # module.Graph
(*)注意,你真的一定不能用2.6;它已过时且不受支持。如果你坚持2.x至少使用2.7;但实际上你应该使用3.x,除了其他任何东西之外,它还会修复你原来的问题。
答案 2 :(得分:0)
由于Python是动态类型的,因此无法在Python中强制执行类型。
可能的解决方案是在运行时检查实例类型。
首先,从object
继承你的班级(即新的&#39;对象):
class Node(object):
# your code here
class Graph(object):
# your code here
然后你可以在运行时进行类型检查:
>>> g = Graph()
>>> type(g)
<class '__main__.Graph'>
>>> isinstance(g, Graph)
True
答案 3 :(得分:0)
Python是动态类型语言。在使用变量之前不需要声明变量,也不需要声明它们的类型。
你可以这样做:
foo = 1 # this is an integer
foo = "string" # this is a string
变量foo
将包含存储在其中的值的类型。
在Python中,您可以在同一个列表中存储不同类型的对象,如果您只想强制存储一种类型,则可以对内置的list
类进行子类化。