Subclassing Graph from the graph_tool package

2019-08-01 05:58发布

问题:

I am attempting to sub-class Graph from the graph_tool package for some graph analysis in Python (so that I can generate some of my own functions, but still use Graph_Tool's functions as well), and I cannot seem to use graph_tool's graph generator methods.

I start by importing my classes:

import graph_tool.all as gt
import numpy.random as np
np.seed(42)

I've tried various versions of the __init__ method:

  1. Build a graph from scratch. This works, but I'd prefer not to use this, because graph_tool has some nice ways to pre-populate your graphs (see 2. and 3. below).

    class myGraph(gt.Graph):
        def __init__(self): 
            super(myGraph, self).__init__()
            self.add_vertex(4)
    
  2. Use graph_tool graph generator methods. This generates a gt.Graph object inside the function. But when I try to print the object outside the function, I get an error.

    class myGraph(gt.Graph):
        def __init__(self):
            self = gt.collection.data['celegansneural']
            print self
    g = myGraph()
    print g
    

The above code returns (note the first line is the result of print self in my `init method):

     <Graph object, directed, with 297 vertices and 2359 edges at 0x1049d2a50> 
     Traceback (most recent call last): <br>
     File "Graph_Tool.py", line 54, in <module> <br>
        print g <br>
      File "/usr/local/lib/python2.7/site-packages/graph_tool/&#95;_init__.py", line 1683, in &#95;_repr__ <br>
        d = "directed" if self.is_directed() else "undirected" <br>
     File "/usr/local/lib/python2.7/site-packages/graph_tool/&#95;_init__.py", line 2412, in is_directed <br>
        return self.__graph.get_directed() <br>
    AttributeError: 'myGraph' object has no attribute '_Graph__graph'
  1. My other approach is to call the parent's __init__ but then override the object with new data. When I do this, everything looks fine as long as I stay in my __init__ method, but once I leave it, my graph is wiped.

    class myGraph(gt.Graph):
        def __init__(self):
            super(myGraph, self).__init__()         
            self = gt.collection.data['celegansneural']
            print self
    g = myGraph()
    print g
    

Which returns the following. Note the first print self returns a populated Graph object, whereas the second print g returns an empty myGraph object

<Graph object, directed, with 297 vertices and 2359 edges at 0x11df610d0>
<myGraph object, directed, with 0 vertices and 0 edges at 0x109d14190>

I apologize in advance if this is some picky problem of graph_tool, library, but I figured that it is more likely my coding error than theirs.

回答1:

You seem a bit confused about how assignment works in python. But I suppose the correct way to achieve what you want is to call the parent's constructors with the appropriate arguments:

class myGraph(gt.Graph):
    def __init__(self):
        super(myGraph, self).__init__(gt.collection.data['celegansneural'])
g = myGraph()
print(g)


回答2:

You should generally prefer composition over inheritance -- unless you want to customize the behavior of the graph class itself, you don't need to subclass gt.Graph, just have one as a member of your own class. Then you can add your own methods to your class, and use the graph's methods when you need to:

class MyGraph(object):
    def __init__(self, graph):
        self.graph = graph

    def do_stuff(self):
        # do stuff with self.graph

# Usage:
my_graph = MyGraph(graph=gt.collection.whatever())
my_graph.do_stuff()