当前位置: 首页 > 面试题库 >

全局词典不需要关键字global来修改它们吗?

丁承德
2023-03-14
问题内容

我不知道为什么我可以不使用global关键字来更改全局词典?为什么对其他类型是强制性的?这背后有逻辑吗?

例如代码:

#!/usr/bin/env python3

stringvar = "mod"
dictvar = {'key1': 1,
           'key2': 2}

def foo():
    dictvar['key1'] += 1

def bar():
    stringvar = "bar"
    print(stringvar)

print(dictvar)
foo()
print(dictvar)

print(stringvar)
bar()
print(stringvar)

得到以下结果:

me@pc:~/$ ./globalDict.py 
{'key2': 2, 'key1': 1}
{'key2': 2, 'key1': 2}  # Dictionary value has been changed
mod
bar
mod

我期望的地方:

me@pc:~/$ ./globalDict.py 
{'key2': 2, 'key1': 1}
{'key2': 2, 'key1': 1}  # I didn't use global, so dictionary remains the same
mod
bar
mod

问题答案:

原因是行

stringvar = "bar"

是模糊的,也可能是指一个全局变量, 或者
它可以被称为创建新的本地变量stringvar。在这种情况下,除非global已使用关键字,否则Python默认将其假定为局部变量。

但是,线

dictvar['key1'] += 1

完全是明确的。它只能引用全局变量dictvar,因为dictvar必须已经存在该语句才不会引发错误。

这并非仅针对字典-列表也是如此:

listvar = ["hello", "world"]

def listfoo():
    listvar[0] = "goodbye"

或其他种类的物体:

class MyClass:
    foo = 1
myclassvar = MyClass()

def myclassfoo():
    myclassvar.foo = 2

每当使用mutation操作而不是重新绑定操作时,都是如此。



 类似资料:
  • 为什么我们需要字典? 计算机最适合使用数字,而人类最适合使用姓名。我们创建了DNS以便记住主机名而不是IP地址。字典以相同的方式使用,因此我们可以记住AVP名称而不是类型编号。当FreeRADIUS解析请求或生成响应时,会查阅字典。 但是,字典与DNS不同,因为RADIUS客户端不知道FreeRADIUS使用的这些“友好”名称。永远不会在RADIUS客户端和RADIUS服务器之间交换AVP名称。

  • 考虑一个无状态EJB 从EJB3.1规范中 容器将支持并发执行的会话 bean的许多实例;但是,每个实例只看到一个 序列化的方法调用序列。因此,有状态或 无状态会话bean不必被编码为可重入的 因此无状态seession bean一次最多只能“服务”一个请求,这通常是由管理bean池的容器实现的。这一切的伟大目标是线程安全。 我的问题是为什么我们需要这种形式的线程安全?我的意思是Spring be

  • 问题内容: 因此,似乎无法执行以下操作(由于没有方法,因此会引发错误): 并且必须使用以下旧技巧: 有没有一种简单/干净的方法(也许可以单独设置-和-轴参数,等等)? PS如果没有,为什么? 问题答案: 上面的答案无效,如注释中所述。我建议使用刺。

  • 这些对象在所有模块中都是可用的。 有些对象实际上不在全局作用域内,而是在模块作用域内,这个在文档中会注明。 以下列出的对象是特定于 Node.js 的。 有些内置对象是 JavaScript 语言本身的一部分,它们也可以全局访问。 Buffer 类 新增于: v0.1.103 <Function> 用于处理二进制数据。详见 buffer 章节。 __dirname 新增于: v0.1.27 <st

  • Node.js全局对象本质上是全局的,并且它们在所有模块中都可用。 我们不需要在我们的应用程序中包含这些对象,而是可以直接使用它们。 这些对象是模块,函数,字符串和对象本身,如下所述。 __filename __filename表示正在执行的代码的文件名。 这是此代码文件的已解析绝对路径。 对于主程序,这不一定与命令行中使用的文件名相同。 模块内部的值是该模块文件的路径。 例子 (Example)

  • 问题内容: 我正在尝试使用Carbon的功能为按下命令键时创建一个热键。我这样使用它: 但是,仅使用命令键时不会调用。如果我替换为其他任何非修饰键代码,则将调用处理程序。 有没有人有任何建议可以让应用程序在按下命令键时全局识别?谢谢。 问题答案: 您可以将与事件匹配的“全局事件监控器”添加到视图控制器,以便您可以检查它的modifierFlags与deviceIndependentFlagsMas