In the following code, Graph() is acting as a proxy to Vertex and Edge -- clients only access Vertex and Edge through Graph():
from rest import Resource
from elements import Vertex, Edge
class Graph(object):
def __init__(self,db_url):
self.resource = Resource(db_url)
self.vertices = Vertex
self.edges = Edge
g1 = Graph('http://localhost/one')
g2 = Graph('http://localhost/two')
What are the best ways for Vertex and Edge to access the resource object, without having to pass it as a param to Vertex and Edge?
One of the reasons I don't want to pass it as a param is because Vertex and Edge have classmethods, such as create(), that need access to the resource object too.
Flask/Werkzeug uses "context locals" (http://werkzeug.pocoo.org/docs/local/) -- is that the right approach here, or is there a better way?
If your resource object is unique, could you make it a singleton? The fact that you want to use it from a class method makes me think that it's probably the case. If its only purpose is to provide the database connection, could you consider using a connection pool?
If you still need to pass it to your classes, you can simply assign it to class attributes.
class Vertex(object):
@classmethod
def foo(cls):
print cls.resource
Vertex.resource = 'something'
v = Vertex()
v.foo()
This can also be done in __init__
:
class Vertex(object):
def __init__(self, resource):
if not hasattr(self.__class__, 'resource'):
self.__class__.resource = resource
@classmethod
def foo(cls):
print cls.resource
resource = 'some resource'
v = Vertex(resource)
v.foo()
But really my intuition is that you should look into using a singleton, which in many cases can be implemented in Python simply as a module.
Finally if I can make a couple of remarks about your code, I find it confusing that you're assigning classes to plural variable names. When I see self.edges
I would expect a collection or an iterable, not a class. I also wonder why you would want a class method called create
. What does it do that __init__
cannot do?