При использовании прокси-шаблона в Python, как прокси-классы могут обращаться к состоянию в вызывающем объекте? - PullRequest
0 голосов
/ 28 июня 2011

В следующем коде Graph () действует как прокси для Vertex и Edge - клиенты получают доступ только к 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?

Одна из причин, по которой я не хочу передавать его как параметр, заключается в том, что у Vertex и Edge есть методы классов, такие как create (), которым тоже нужен доступ к объекту ресурса.

Flask / Werkzeug использует "контекстные локальные" (http://werkzeug.pocoo.org/docs/local/) - это правильный подход здесь, или есть лучший способ?

1 Ответ

1 голос
/ 28 июня 2011

Если ваш ресурсный объект уникален, можете ли вы сделать его одноэлементным?Тот факт, что вы хотите использовать его из метода класса, заставляет меня думать, что это, вероятно, так.Если его единственной целью является предоставление соединения с базой данных, не могли бы вы рассмотреть возможность использования пула соединений?

Если вам все еще нужно передать его своим классам, вы можете просто назначить его атрибутам класса.

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__ не может сделать?

...