Атрибуты доступа Python вмещающего класса (не родительского) - PullRequest
0 голосов
/ 17 октября 2011

У меня есть простая проблема, я разрабатываю что-то, для чего мне нужно, чтобы некоторые классы обращались к некоторым распространенным переменным, таким как:

somevar="foo"

class A(SomeParent):
  def eval_class(self):
     global somevar
     return somevar

def index(request,input_somevar):
  global somevar
  somevar=input_somevar
  return HttpResponse(A().eval_class())

Проблема: этот код работает на django, поэтому каждый запроскод все еще будет работать, а somevar получит новое значение.Если запросы перекрываются, я включу значения somevar для одного запроса, которые устанавливаются другим запросом.

Решение?Мне пришло в голову использовать экземпляры одного класса.

Class Parent:
  somevar=None
  def set_somevar(self,somevar):
    self.somevar=somevar

  class A(SomeParent): #Note: the parent of this class is NOT "Parent".
    def eval_class(self):
      #Here I would like to retrieve somehow "somevar"
      return somevar

def index(request,input_somevar):
  p=Parent()
  p.set_somevar(input_somevar)
  return HttpResponse(p.A().eval_class())

ПРИМЕЧАНИЕ: Я не могу передавать переменные в классы, они должны иметь возможность доступа к "вмещающему"но не родительский класс », так как они являются классами функций sympy, которые необходимо передать интерпретатору sympy.

Заранее спасибо!

Ответы [ 4 ]

1 голос
/ 17 октября 2011

По сути, вы говорите, что разные потоки вашего приложения Django имеют конфликт доступа: когда один из них читает значение somevar, другой изменяет его.

Итак, вы, кажется, решаете не ту проблему. На самом деле вам нужно спроектировать ваше приложение так, чтобы не возникало конфликтов доступа.

Идеальным решением было бы отсутствие общего состояния вообще. Используйте threading.local для хранения данных, доступных только одному (текущему) потоку. Однако вам придется разобраться с проблемами сходства: если один запрос переходит к этому потоку, а следующий запрос того же клиента, через несколько минут, переходит к другому потоку, он не увидит данные, заданные предыдущим запросом.

Другим решением будет использование базы данных для сериализации изменений. Возьмите SQLite, он почти невесом и поддерживает транзакции. Одно изменение блокирует запись somevar для обновления, а другая транзакция, которая изменит ее, завершится неудачей. Вам придется снова разобраться в этом осмысленно.

Было бы полезно, если бы вы описали большую проблему, которую вы решаете.

0 голосов
/ 17 октября 2011

Почему бы просто не передать input_somevar классам, которые в этом нуждаются?

class A(SomeParent):
    def eval_class(self, somevar):
        return somevar

def index(request,input_somevar):
    return HttpResponse(A().eval_class(input_somevar))

Если ваше представление вызывает другие классы, передайте его им, если они в этом нуждаются.

0 голосов
/ 17 октября 2011

В отличие от java, вложенные классы не связаны с экземплярами внешнего класса. Он просто меняет пространство имен, в котором доступен класс. Это означает, что p.a - это то же самое, что и Parent.A.

Как сказал Брайан, самое простое, что можно сделать, это просто передать переменные, которые вам нужны, из вашего представления.

0 голосов
/ 17 октября 2011

с set_somvevar() вы устанавливаете значение атрибута экземпляра p, в то время как глобальный somevar остается неизменным.Таким образом, p.A().eval_class() всегда будет возвращать None (исходное значение).

edit: с глобальным somevar, определенным как атрибут класса вместо атрибута экземпляра, установка этого атрибута не решит вашу проблему: вы все еще получаете последнее установленное значение этого атрибута класса, предполагая, что вы имели в виду eval_class для возврата P().somevar.

Как насчет того, чтобы сделать Parent-экземпляр переменной для функции A-init?

class Parent:
    def __init__(self, somevar):
        self.somevar = somevar

    class A(SomeParent):
        def __init__(self, parent):
            SomeParent.__init__(self)
            self.parent = parent

        def eval_class(self):
            return self.parent.somevar

def index(request,input_somevar):
  p = Parent(input_somevar)
  return HttpResponse(p.A(p).eval_class())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...