首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于全局和不可变的混淆

关于全局和不可变的混淆
EN

Stack Overflow用户
提问于 2016-11-08 14:06:11
回答 3查看 123关注 0票数 0

我对global和不可变变量非常困惑。我有这样的代码:

代码语言:javascript
复制
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()

它的输出是:

代码语言:javascript
复制
0
value:  5
final:  5
value:  3
final:  5

但是我不明白为什么对于"c“,如果RR是一个不可变的对象,那么它的值是5。以及为什么"d“使用全局no会降低RR的值。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-11-08 15:19:18

这和不变性无关..。但不管怎样:

代码语言:javascript
复制
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“。

您可能希望运行这个“扩展”版本的脚本,以了解实际情况:

代码语言:javascript
复制
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()
票数 1
EN

Stack Overflow用户

发布于 2016-11-08 14:10:39

函数d将修改(在创建它之后)全局命名空间中的RR值,而不是作为实例变量的self.RR;也就是说,您根本没有改变self.RR

因此,当您在RR中打印d时,3将被打印出来,这是您分配给全局RR的值。

如果也在self.RR中打印d,您将看到它们只是位于不同名称空间中的两个相似的名称(每个名称空间都保存了相应的值):

代码语言:javascript
复制
 def d(self):
    global RR
    RR = 3
    print("valor: ", RR)
    print("self.RR ", self.RR)

打印出来:

代码语言:javascript
复制
valor   : 3
self.RR : 5
票数 2
EN

Stack Overflow用户

发布于 2016-11-08 15:53:01

非常感谢!!现在我明白了。现在,通过您的示例,我更好地理解python的工作原理和上下文。但对于我来说,还有一个小小的问题,那就是永恒不变。如何使变量不可变?如果我更改他的值并再次调用该变量,则该值已被更改。有了这段代码,你就能明白我的意思了。

代码语言:javascript
复制
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("=================") 

和返回;

代码语言:javascript
复制
=================
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的值时,阻止这个操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40488969

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档