0

我已经学习 Python 三个月了,现在我有一个使用 google 无法解决的问题,但幸运的是我能够在这里简化它:

我有一个 var_class 模块:

#var_class.py

class A(object):
    def __init__(self, x):
        self.x = x+2

zz = A(10)

class B():
    b = 0    
    def __init__(self):
        pass
    def update(self):
        B.b = zz.x

在主程序中我有:

#main.py

from var_class import *

b_class = B()
b_class.b        # I get 0 as expected
zz = A(100)
b_class.update()
b_class.b        # Instead of 102, I get 12 unexpectedly

您会看到我的目标是为每个数据输入频繁更改“zz”,然后更新类变量“b”,而我在 var_class.py 中编写 zz = A(10) 的原因是,否则当我导入它时,模块' var_class'在'class B'中缺少'zz',它会给出错误“未定义全局名称zz”。

但是,当我现在这样写时,看起来值“10”被粘在类上,我无法在主程序中更改它。不知道如何克服这一点。提前感谢您的帮助。

回答:

alKid先写了完整的答案,还要感谢alexvassel和C先生,想知道是否有办法感谢他们,其他人帮助我了解了知识,也非常感谢。

4

6 回答 6

1

当你这样做B.b = zz.xupdate方法)时,你在模块内var_class,所以zzA(10)

于 2013-10-09T12:57:54.980 回答
1

容易理解:你不能那样做,你在模块里面var_class,所以.zzA(10)

将 zz 作为参数传递怎么样?像这样!

class A(object):
    def __init__(self, x):
        self.x = x+2

zz = A(10)

class B():
    b = 0    
    def __init__(self):
        pass
    def update(self, zz):
        B.b = zz.x

希望这可以帮助!

于 2013-10-09T13:06:27.653 回答
1

python 运行时按命名空间查找变量。命名空间类似于范围。当Bb = zz.x执行时,运行时首先搜索本地命名空间(函数命名空间--update),它没有看到zz。然后,它进入模块空间(var_class),我们得到变量并停止搜索。

python命名空间搜索顺序:
1.本地命名空间,函数作用域
2.全局命名空间,模块作用域
3.内置命名空间

最好不要使用全局变量。

你的代码可能是这样的:

class B():
b = 0    
def __init__(self):
    pass
def update(self, zz):
    B.b = zz.x
于 2013-10-09T13:08:39.493 回答
0

那是范围问题!您在 main.py 中使用 zz = A(100)。但是当您调用 b_class.update() 时,b_class 必须获取“some2 变量,称为“zz”——可用的变量是您在 class.py 中定义的变量——并且这个变量的值仍然是 A(10) !!!

要解决此问题,您有不同的选择。

  • 肮脏的黑客(但最接近您的解决方案)将是定义一个global变量并使用 ist(谷歌“python globals”以获取有关此方法的更多信息)。
  • 我建议将 A(或 Ax)传递给您的“更新”方法b_class.update(A.x)。这避免了全局变量并且更具可读性。当然,您必须为新参数调整 B.update。
于 2013-10-09T13:04:54.487 回答
0

当你从一个模块中导入一个变量时,你会得到一个变量的副本,而不是原来的。您需要直接写入原件。

from a.b import c
from a.b.c import var

a.b.c.var = 1

var = 2

a.b.c.var
1
var
2

编辑:所以,更准确地说,在 python 中,内存中有对象,然后有对象的名称。当您导入一个模块时,您会创建两个单独的名称,但它们都指向同一个对象——即它们具有对同一个对象的引用。它与下面的代码非常相似,根本不需要任何导入:

>>> a = 4
>>> b = a
>>> b
4
>>> a
4
>>> b = 'something different'
>>> b
'something different'
>>> a
4

为什么改变 b 不改变 a?顺序是这样的:首先,我们创建一个对象(4)并将名称“a”指向它。然后,我们创建一个名称“b”,并将其指向同一个对象。因此,现在查找这些名称会返回相同的对象。现在,然后我们返回并将名称“b”指向一个不同的对象,一个字符串。指向的对象“a”仍然存在,并且没有改变。

新用户更经常以另一种方式绊倒,使用列表之类的对象:

>>> a = [1,2,3,4,5]
>>> b = a
>>> b
[1,2,3,4,5]
>>> a
[1,2,3,4,5]
>>> b.append(6)
>>> b
[1,2,3,4,5,6]
>>> a
[1,2,3,4,5,6]
>>> b = b[1:3]
>>> b
[2,3]
>>> a
[1,2,3,4,5,6]

这里发生了什么?好吧,首先我们创建一个列表对象,然后将名称“a”指向它。然后我们创建名称“b”并将其指向同一个对象。所以,'a' 和 'b' 都指向同一个列表。然后,我们使用引用 b 来获取对象并对其进行修改。请注意,在这种情况下,我们没有更改 'b' 指向的内容——我们获取了引用,然后直接修改了它指向的对象。因此,在这种情况下,“a”和“b”都会看到变化——它们都指向修改后的对象。然后,我们提取一个切片,并将其分配给“b”。现在,这实际上创建了一个对象,并将“b”指向它——“b”不再指向原始对象。所以现在'a'和'b'

导入案例只是其中的一个特例。

于 2013-10-09T13:06:58.813 回答
-1

也许你可以这样做

class B():
    b = 0    
    def __init__(self):
        pass
    def update(self,value):
        self.b =self.b+value
于 2013-10-09T13:05:46.137 回答