0

在下面的代碼,圖()充當代理點和邊 - 客戶只能通過圖表()訪問頂點和邊:在Python中使用代理模式時,代理類如何在調用對象中訪問狀態?

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有classmethods,如create(),也需要訪問資源對象。

燒瓶/ Werkzeug使用「上下文當地人」(http://werkzeug.pocoo.org/docs/local/) - 這是正確的方法,還是有更好的方法?

+0

通過代理你的意思只是另一個參考? – 2011-06-28 03:25:20

+0

在這種情況下,Graph()充當Vertex和Edge的代理,因爲客戶端只通過Graph()訪問Vertex和Edge。 – espeed

+1

您可能想要停止使用「代理對象」,並且改爲了解「依賴注入」,儘管python粉絲傾向於忽略那些說解釋器本身是依賴注入框架(因爲您可以動態更改類的名稱以適應您的情況) – Arafangion

回答

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__不能做什麼?

+0

嗨亞歷克斯 - 感謝您的反饋。 Vertex和Edge類提供了與圖形數據庫交互的接口,比如graph.vertices.get_all()和graph.edges.get(edge_id)等等。你是否建議將它們重命名爲graph.vertex.get_all()等?在創建資源對象時,db_url作爲參數傳入,圖形API爲用戶提供了在創建圖形對象時通過傳入不同的DB URL來訪問多個數據庫的功能。我已經研究過使用模塊作爲全局單例,但是這在使用不同的URL創建兩個圖形對象時遇到了問題。 – espeed

+1

好的我認爲問題在於你正在試圖讓類像對象一樣行爲。你正試圖讓類根據數據動態改變它們的行爲。這真的是對象的目的。我建議你引入容器類來管理你的頂點和邊。 –

+0

順便說一句,正如Arafangion所建議的那樣,您不是在這裏進行代理,因爲您可以直接訪問您打算代理的對象。要說服自己,請問問自己,如何記錄或計算對「代理」對象(代理的典型用例)的訪問權限。 –