2011-10-17 53 views
0

我有一个简单的问题,Python的访问属性,我开发我需要有一些类访问一些常见的变量类似的东西:一个封闭类(不父)

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的功能类。

预先感谢您!

回答

1

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

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

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

另一种解决方案是使用数据库来序列化更改。拿SQLite来说,它几乎没有重量并支持事务。一个更改锁定了更新的记录,另一个更改它的事务将失败。你必须以有意义的方式再次分类。

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

+0

基本上这个问题比较复杂。我收到一些输入,我调用一个库来执行一些数据库上的大量map/reduce操作。该操作需要几秒钟。因此,如果在此期间我收到其他输入,map/reduce进程将开始读取新输入(与前一个输入无关)。我应该重新设计一部分代码来使用threading.local吗? docs是相当隐晦的.. – luke14free

+0

伟大的,这解决了我的问题,封装在一个线程中的功能,然后使用本地工作就像一个魅力没有改变太多的代码。你只是让我的一天;) – luke14free

+0

@ user999346:很高兴听到! ) – 9000

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()) 
+0

在底层代码片段中,somevar是一个类属性,所以self.somevar = somevar确实会修改类的属性,而不仅仅是实例。这些修改将持续存在于各种请求中,这对于观点的争论通常不是好事。 –

+0

这是事实,但对我没有多大帮助。 ;) – luke14free

+0

最后编辑看起来很有希望我会试试看,谢谢! – luke14free

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)) 

如果你的视图调用其他类,如果他们需要它也可以传递给它们。

+0

我不行。具体来说,它是一类Sympy,它定义了一个特殊的数学函数,除了sympy本身在评估过程中,它不能被“召唤”。 – luke14free

0

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

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