0

別のクラス Vertex を使用する Graph クラスを定義したモジュールがあります。

# Graph.py
class Graph(object):
    def __init__(self):
        self.vertList = {}
        self.numVertices = 0 

    def addVertex(self,key):
        self.numVertices += 1
        newVert = Vertex(key)
        self.vertList[key] = newVert
        return newVert

    def getVertex(self,k):
        if k in self.vertList:
            return self.vertList[k]
        else:
            return None

class Vertex(object):
    def __init__(self,key):
        self.id = key
        self.connectedTo = {}

別のモジュールで使用するために Vertex クラスを拡張したい:

# BFSGraph.py
from Graph import Vertex,Graph

class Vertex(Vertex):
    def __init__(self,key):
        super(Vertex,self).__init__(key)

        # extensions for BFS
        self.predecessor = None
        self.dist = 0 
        self.color = 'w' # white, grey, and black

class BFSGraph(Graph):
    def getColor(self,k):
        return self.getVertex(k).color

def test():
    g=BFSGraph()
    g.addVertex('a')
    g.getColor('a')

テスト ルーチンを実行すると、「'Vertex' object has no attribute 'color'」が返されるため、Vertex に加えた変更は Graph に反映されず、BFSGraph は拡張 Vertex を使用していません。

Graph と BFSGraph に新しい Vertex を使用させるにはどうすればよいですか?

4

3 に答える 3

0

Graph& を明示的に参照するの唯一の部分はVertex、のコンストラクターをaddVertex使用Vertexしてオブジェクトを作成し、それを辞書に詰め込みます。addVertexオブジェクトを引数として追加するように変更することをお勧めしVertexます。これにより、呼び出し元に構築を行わせ、Vertex使用するクラスを決定させることができます。次に例を示します。

def addVertex(self, key, newVert):
    self.numVertices += 1
    self.vertList[key] = newVert
    return newVert

または、次のように単純に追加した後、冗長な引数を減らすためにVertex:

def addVertex(self, newVert):
    self.numVertices += 1
    self.vertList[newVert.getKey()] = newVert
    return newVert
于 2013-10-29T20:14:25.747 に答える
0

正しいことは、Graphクラスがユーザー定義のクラスを引数として取り、それを使用して頂点を表現できるようにすることです。モジュールgraphは適切なデフォルトを提供できます。

In graph.py(モジュールは小文字で始める必要があります):

class Vertex(object):
    def __init__(self,key):
        self.id = key
        self.connectedTo = {}

class Graph(object):
    def __init__(self, vertexclass=Vertex):
        self.vertList = {}
        self.numVertices = 0 
        self.vertexclass = vertexclass

    def addVertex(self,key):
        self.numVertices += 1
        newVert = self.vertexclass(key)
        self.vertList[key] = newVert
        return newVert

    def getVertex(self,k):
        if k in self.vertList:
            return self.vertList[k]
        else:
            return None

唯一の変更点はGraph.__init__、デフォルト値がプレーン クラスであるパラメーターがあり、インスタンスVertexを作成するときに別のクラスを渡すことができることです。そのクラスは保存され、新しい頂点を作成するために が呼び出されるGraphたびにそれを使用します。addVertex

次に、カスタム頂点クラスを使用する別のモジュールまたはスクリプトで:

#!/usr/bin/python
import graph

class MyVertex(graph.Vertex):
    def __init__(self,key):
        super(Vertex,self).__init__(key)

        # extensions for BFS
        self.predecessor = None
        self.dist = 0 
        self.color = 'w' # white, grey, and black

class BFSGraph(Graph):

    def __init__(self):
        super(BFSGraph, self).__init__(MyVertex)

    def getColor(self,k):
        return self.getVertex(k).color


def test():
    g=BFSGraph()
    g.addVertex('a')
    g.getColor('a')    

あなたのは、呼び出されたときに、使用したいサブクラスでその親をBFSGraph.__init__呼び出すだけです。__init__graph.Vertex

これはコードを編成する唯一の方法ではありませんが、覚えておくべき重要な点はGraph、頂点を実装するクラスが実装する必要がある動作を、クラス (またはその派生クラス) が正確に文書化する必要があるということです。

于 2013-10-29T20:23:09.080 に答える