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

发布于 2024-12-10 09:02:00 字数 942 浏览 0 评论 0原文

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

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 的 Function 类,需要传递给 sympy 解释器。

先感谢您!

I have a simple problem, I'm developing something for which I need to have some classes accessing some common variables like that:

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

Problem: That code runs on django so, every request the code will be still running and the somevar will reiceve a new value. If requests happen to overlap I'll enp up having values of somevar for one request which are set by another request.

Solution? What came to my mind was to use instances of a single class.

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

NOTE: I cannot pass variables to the classes, they have to be able to access to the "enclosing but not parent class" as they are sympy's Function classes which need to be passed to the sympy interpreter.

Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

澉约 2024-12-17 09:02:01

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

正如布莱恩所说,最简单的事情可能就是从你的视图中传递你需要的变量。

Unlike in java, nested classes are not linked to instances of the outer class. It just changes the namespace in which the class is available. That means p.a is the same thing as Parent.A.

As Brian said, the simplest thing to do might be to just pass the variables you need from your view.

长安忆 2024-12-17 09:02:01

使用 set_somvevar() 您可以设置实例 p 的属性值,而 somevar 全局保持不变。因此,pA().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())

with set_somvevar() you are setting the value of the attribute of the instance p, while the somevar global remains unchanged. Thus, p.A().eval_class() will always return None (the original value).

edit:
with the global somevar defined as a class attribute instead of an instance attribute, setting this attribute will not solve your problem: you still get the latest set value of this class attribute, assuming you meant
with eval_class to return P().somevar.

What about making the Parent-instance a variable to the A-init function?

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())
你是我的挚爱i 2024-12-17 09:02:00

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

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

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

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

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

Basically you say that different threads of your Django app have an access conflict: while one of them is reading the value of somevar, another is modifying it.

So you seem to be solving a wrong problem. Really you need to design your application in a way that access conflicts do not happen.

An ideal solution would be having no shared state at all. Use threading.local to store data accessible to only one (current) thread. You will have to sort out affinity issues, though: if one request goes to this thread and the next request of the same client, minutes later, goes to another thread, it will not see the data set by the previous request.

Another solution would be using a database to serialize the changes. Take SQLite, it's almost weightless and supports transactions. One change locks the somevar record for update, and another transaction that would change it will fail. You'll have to sort this out, again, in a meaningful manner.

It would help if you described the bigger problem you're solving.

庆幸我还是我 2024-12-17 09:02:00

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

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

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

如果您的视图调用其他类,请将其也传递给那些需要的类。

Why not just pass input_somevar to the classes that need it?

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

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

If your view calls other classes, pass it to those too if they need it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文