graph_tool library is based on boost C++ library and provides Vertex class binding for Python. If we wanted to extend this Vertex class and add some attributes and methods, it wouldn't let us do that due to private constructor in C++ code (RuntimeError: This class cannot be instantiated from Python). We can overcome this obstacle using Proxy pattern.
In the __getattr__ method, if the attribute(or function name) is not in the Subclass MyVertex, then it looks for attributes of Vertex object that is defined inside MyVertex.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | from graph_tool.all import Vertex, Graph
class MyVertex:
def __init__(self, g):
self.g = g
self.v = g.add_vertex()
self.halted = False
def vote_for_halt(self):
self.halted = True
def __getattr__(self, attr):
return getattr(self.v, attr)
if __name__ == "__main__":
g = Graph()
v1 = MyVertex(g)
v2 = MyVertex(g)
g.add_edge(v1, v2)
v1.vote_for_halt()
print v1.out_degree() # will print 1
print v1.halted # will print True
print v1.foo # will raise error: AttributeError: 'Vertex' object has no attribute 'foo'
|
The
__getattr__()
object method is only called for attributes that are not found in the "usual places", according Python 2's documentation. This means that theif/else
clause in yourMyVertex
version isn't necessary and the code for the whole method could be reduce to simply:Thank you, I didn't know that! I'm fixing it.