<p>基本上,如果不修改<code>Graph</code>和<code>BFSGraph</code>类,就不能这样做。如果<code>Graph</code>引用了<code>Vertex</code>,那么它引用了<code>Vertex</code>,如果不实际更改<code>Graph</code>的代码,就不能让它引用其他任何东西。也就是说,有三种方法可以做到这一点。你知道吗</p>
<p>最简单的解决方案是生成一个<code>Graph</code>的派生版本来覆盖<code>addVertex</code>,这样它就使用了新的<code>Vertex</code>子类。然后使用新类而不是原来的<code>Graph</code>,一切正常。你知道吗</p>
<p>第二种、更狡猾、更危险的方法是monkeypatch:</p>
<pre><code>import graph
graph.Vertex = MyNewVertex
</code></pre>
<p>现在,任何试图使用<code>Vertex</code>模块中的<code>graph</code>类的东西实际上都将使用您的类。不过,这是有风险的,因为您永远不知道它会对其他认为使用原始<code>Vertex</code>的代码做什么。(给你的类起个不同的名字仍然是个好主意,否则就很难分辨出使用的是哪一个了。)另外,如果在monkeypatch生效之前另一个类导入了<code>Vertex</code>,它也会默默地失败。你知道吗</p>
<p>如果要设计整个代码库,并且确实需要经常这样做,那么更大规模的解决方案是将顶点参数化为类的一部分。这使得编写彼此互操作的派生类变得更容易。也就是说,你可以这样做:</p>
<pre><code>class Graph(object):
vertexClass = Vertex
def addVertex(self, key):
# ...
newVert = self.vertexClass(key)
# etc.
# etc.
</code></pre>
<p>以后如果需要,您可以:</p>
<pre><code>class MyVertex(Vertex):
# blah
class MyGraph(Graph):
vertexClass = MyVertex
</code></pre>
<p>其思想是使用一个类变量,以便Graph类知道对其顶点使用哪个类。然后,您可以轻松地创建一个只更改此变量的派生类,而不必重写所有实际的方法代码(假设您确实在MyVertex类中保持了相同的API)。这增加了一层间接性,对于小型项目来说可能有点过分,但是如果您有很多相互依赖的类,那么让它们显式地跟踪它们需要如何相互使用是非常有用的。你知道吗</p>