2017-02-14 80 views
0

我是Python新手,對Python 2.6中的類及其屬性有疑問。Python中的類和定義屬性類型

可以說我有一個這樣的類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 

和A類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?

回答

0

這些都不是你寫Python的方式;它看起來像Java而已。

你不需要在課堂上「聲明」屬性;這樣做的唯一原因是使用在所有實例之間共享的值,這是因爲您立即用實例屬性覆蓋了這些值。刪除這些定義。

寫getter和setter方法也是非常單一的,特別是如果他們只返回屬性。您的調用代碼應直接訪問屬性。

至於你的問題,因爲你使用Python 2 [*]你的類必須繼承對象。如果你這樣做,你會看到正確的類型:

class Graph(object): 
    ... 

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

(*)注意,你真的不能使用2.6;它已過時並且不受支持。如果你在2.x上至少使用2.7;但真的你應該使用3.x,除了其他任何東西修復你的原始問題。

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): 
    ... 

如果你這樣做,打印賬單會顯示你c姑娘。如果沒有做到這一點,就可以在Python早期就爲你提供老式的類,而且你會發現像屬性不能正確使用它們。

0

由於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 
0

Python是動態類型語言。在使用它們之前不需要聲明變量,或者聲明它們的類型。

你可以做這樣的東西:

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

可變foo將存儲在它的值的類型。

在Python中,您可以在同一個列表中存儲不同類型的對象,如果您只強制執行一種類型的存儲,則可以繼承內部list類。