我对global和不可变变量非常困惑。我有这样的代码:
class ProcessObject:
RR = 0
def b(self):
self.RR=5
print("valor: ", self.RR)
def c(self):
print("final: ", self.RR)
def d(self):
global RR
RR = 3
print("valor: ", RR)
print(RR)
proce = ProcessObject()
proce.b()
proce.c()
proce.d()
proce.c()它的输出是:
0
value: 5
final: 5
value: 3
final: 5但是我不明白为什么对于"c“,如果RR是一个不可变的对象,那么它的值是5。以及为什么"d“使用全局no会降低RR的值。
发布于 2016-11-08 15:19:18
这和不变性无关..。但不管怎样:
class ProcessObject:
# this "RR" lives in the `class` statement namespace,
# it's accessible as 'RR' in this namespace. After the
# `class` statement is executed, it becomes an attribute
# of the `ProcessObject` class, accessible as `ProcessObject.RR`,
# and thru instances as `ProcessObject().RR`.
#
RR = 0
def b(self):
# this creates an "RR" instance attribute
# on the current instance (`self`), which shadows
# the "RR" class attribute
self.RR=5
print("valor: ", self.RR)
def c(self):
print("final: ", self.RR)
def d(self):
# The two following lines creates a module-global
# name "RR", which is distinct from the two previous
# ones.
global RR
RR = 3
print("valor: ", RR)
# this prints the value of the `RR` living in the class
# statement scope - NOT the value of the yet non-existing
# global RR
print(RR)
proce = ProcessObject()
proce.b() # this creates the `proce.RR` instance attribute
proce.c()
proce.d()
proce.c()但是我不明白为什么对于"c“,如果RR是一个不可变的对象,那么它的值是5。
它打印'5‘,因为在调用proce.RR时将该值分配给proce.b()。你混淆了名字和价值观..。RR不是对象,它是绑定到对象的名称。事实上,它在某一点上绑定到一个不可变的对象并不意味着您不能将它重新绑定到另一个对象(不管是否可变,这在这里是无关紧要的)。
以及为什么"d“使用全局no使RR的值降低。
在这里,您混淆了绑定(赋值)和变异。绑定(赋值)的意思是“使名称指向此对象”,变异的意思是“更改此对象的状态”。突变的一个例子是在列表中添加或移除元素,或者倒置列表。
FWIW,对proce.d的调用确实会重新绑定(实际上在第一次调用时绑定)模块-全局"RR“。
您可能希望运行这个“扩展”版本的脚本,以了解实际情况:
print("before : globals = {}".format(globals()))
class ProcessObject:
RR = 0
print "RR defined in the class namespace - not in globals: {}".format(globals())
def __init__(self):
print("in init")
print(" self.__dict__ : {}".format(self.__dict__))
print(" ProcessObject.__dict__ : {}".format(ProcessObject.__dict__))
def b(self):
print("before calling b - self.__dict__ : {}".format(self.__dict__))
self.RR=5
print("valor: ", self.RR)
print("after calling b - self.__dict__ : {}".format(self.__dict__))
def c(self):
print("before calling c - self.__dict__ : {}".format(self.__dict__))
print("final: ", self.RR)
def d(self):
print("before calling d : globals = {}".format(globals()))
global RR
RR = 3
print("valor: ", RR)
print("after calling d : globals = {}".format(globals()))
print(RR)
print("after class statement: globals : {}".format(globals()))
proce = ProcessObject()
proce.c()
proce.b()
proce.c()
proce.d()
proce.c()发布于 2016-11-08 14:10:39
函数d将修改(在创建它之后)全局命名空间中的RR值,而不是作为实例变量的self.RR;也就是说,您根本没有改变self.RR。
因此,当您在RR中打印d时,3将被打印出来,这是您分配给全局RR的值。
如果也在self.RR中打印d,您将看到它们只是位于不同名称空间中的两个相似的名称(每个名称空间都保存了相应的值):
def d(self):
global RR
RR = 3
print("valor: ", RR)
print("self.RR ", self.RR)打印出来:
valor : 3
self.RR : 5发布于 2016-11-08 15:53:01
非常感谢!!现在我明白了。现在,通过您的示例,我更好地理解python的工作原理和上下文。但对于我来说,还有一个小小的问题,那就是永恒不变。如何使变量不可变?如果我更改他的值并再次调用该变量,则该值已被更改。有了这段代码,你就能明白我的意思了。
def e(self):
print("before calling e - ProcessObject.__dict__ : {}".format(ProcessObject.__dict__))
ProcessObject.RR = -7
print("after calling e - ProcessObject.__dict__ : {}".format(ProcessObject.__dict__))
print("=================") 和返回;
=================
before calling e - ProcessObject.__dict__ : {'b': <function ProcessObject.b at 0x006850C0>, '__module__': '__main__', 'RR': 0, '__weakref__': <attribute '__weakref__' of 'ProcessObject' objects>, 'd': <function ProcessObject.d at 0x00685150>, '__doc__': None, 'e': <function ProcessObject.e at 0x00685198>, '__init__': <function ProcessObject.__init__ at 0x00685078>, 'c': <function ProcessObject.c at 0x00685108>, '__dict__': <attribute '__dict__' of 'ProcessObject' objects>}
after calling e - ProcessObject.__dict__ : {'b': <function ProcessObject.b at 0x006850C0>, '__module__': '__main__', 'RR': -7, '__weakref__': <attribute '__weakref__' of 'ProcessObject' objects>, 'd': <function ProcessObject.d at 0x00685150>, '__doc__': None, 'e': <function ProcessObject.e at 0x00685198>, '__init__': <function ProcessObject.__init__ at 0x00685078>, 'c': <function ProcessObject.c at 0x00685108>, '__dict__': <attribute '__dict__' of 'ProcessObject' objects>}
=================
before calling e - ProcessObject.__dict__ : {'b': <function ProcessObject.b at 0x006850C0>, '__module__': '__main__', 'RR': -7, '__weakref__': <attribute '__weakref__' of 'ProcessObject' objects>, 'd': <function ProcessObject.d at 0x00685150>, '__doc__': None, 'e': <function ProcessObject.e at 0x00685198>, '__init__': <function ProcessObject.__init__ at 0x00685078>, 'c': <function ProcessObject.c at 0x00685108>, '__dict__': <attribute '__dict__' of 'ProcessObject' objects>}
after calling e - ProcessObject.__dict__ : {'b': <function ProcessObject.b at 0x006850C0>, '__module__': '__main__', 'RR': -7, '__weakref__': <attribute '__weakref__' of 'ProcessObject' objects>, 'd': <function ProcessObject.d at 0x00685150>, '__doc__': None, 'e': <function ProcessObject.e at 0x00685198>, '__init__': <function ProcessObject.__init__ at 0x00685078>, 'c': <function ProcessObject.c at 0x00685108>, '__dict__': <attribute '__dict__' of 'ProcessObject' objects>}
=================在bruno desthuilliers的代码中,我添加了一个新函数来查看这个值,RR的值从RR=0变为RR=-7,但是我想要做RR不变的事情,当有人试图改变RR的值时,阻止这个操作。
https://stackoverflow.com/questions/40488969
复制相似问题