在Python使用代理模式时,代理类如何访问调用对象的状态?
在下面的代码中,Graph() 就像一个中介,Vertex 和 Edge 只能通过 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')
那么,Vertex 和 Edge 有什么好的方法可以访问资源对象,而不需要把它作为参数传递给它们呢?
我不想把资源对象作为参数传递的原因之一是,Vertex 和 Edge 有一些类方法,比如 create(),也需要访问这个资源对象。
Flask/Werkzeug 使用了“上下文局部变量”(http://werkzeug.pocoo.org/docs/local/)——这样做合适吗,还是有更好的方法呢?
1 个回答
1
如果你的资源对象是唯一的,能不能把它做成单例模式?你想通过类方法来使用它,这让我觉得它可能确实是这样的。如果它唯一的目的就是提供数据库连接,那你有没有考虑过使用连接池呢?
如果你还是需要把它传递给你的类,可以简单地把它赋值给类的属性。
class Vertex(object):
@classmethod
def foo(cls):
print cls.resource
Vertex.resource = 'something'
v = Vertex()
v.foo()
这也可以在 __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()
不过我直觉上觉得你应该考虑使用单例模式,在很多情况下,在Python中可以简单地通过模块来实现。
最后,如果我可以对你的代码说几句,我觉得你把类赋值给复数的变量名有点让人困惑。当我看到 self.edges
时,我会期待它是一个集合或者可迭代的东西,而不是一个类。我也想知道你为什么要有一个叫 create
的类方法。它能做什么是 __init__
方法做不到的呢?