封闭类(不是父类)的Python访问属性

时间:2011-10-17 14:40:49

标签: python django class

我有一个简单的问题,我正在开发一些东西,我需要让一些类访问一些常见的变量,如:

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 个答案:

答案 0 :(得分:1)

基本上你说Django应用程序的不同线程存在访问冲突:其中一个正在读取somevar的值,另一个正在修改它。

所以你似乎在解决一个错误的问题。实际上,您需要以不会发生访问冲突的方式设计应用程序。

理想的解决方案是根本没有共享状态。使用threading.local存储只能访问一个(当前)线程的数据。但是,您必须解决关联性问题:如果一个请求转到此线程并且同一客户端的下一个请求在几分钟后转到另一个线程,则它将看不到先前请求所设置的数据。

另一种解决方案是使用数据库来序列化更改。以SQLite为例,它几乎没有重量并支持交易。一个更改锁定somevar记录以进行更新,另一个将更改它的事务将失败。你必须以有意义的方式再次对此进行排序。

如果您描述了您正在解决的更大问题,那将会有所帮助。

答案 1 :(得分:0)

使用set_somvevar()设置实例p的属性值,而somevar全局保持不变。因此,p.A().eval_class()将始终返回None(原始值)。

编辑: 将全局somevar定义为类属性而不是实例属性,设置此属性将无法解决您的问题:您仍然可以获得此类属性的最新设置值,假设您的意思是 使用eval_class返回P().somevar

如何使Parent-instance成为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())

答案 2 :(得分:0)

为什么不直接将input_somevar传递给需要它的类?

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

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

如果您的视图调用其他类,则在需要时将其传递给其他类。

答案 3 :(得分:0)

与java不同,嵌套类不链接到外部类的实例。它只是更改了类可用的命名空间。这意味着p.aParent.A相同。

正如Brian所说,最简单的方法可能就是从视图中传递所需的变量。