在Python使用代理模式时,代理类如何访问调用对象的状态?

0 投票
1 回答
718 浏览
提问于 2025-04-16 20:25

在下面的代码中,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__ 方法做不到的呢?

撰写回答