Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python局部变量初始化_Python - Fatal编程技术网

Python局部变量初始化

Python局部变量初始化,python,Python,我对python相当陌生,我想知道局部变量是如何工作的。让我们从一个简单方法的示例开始: def do_sth(): local_dict = { 'a': 1, 'b': 2, 'c': 3, ... } ... 让我们假设local_dict像一种常量变量一样使用。问题是:每次调用dou sth()时都会创建它,或者创建一次并保存在dou sth()内部的某个地方?每次调用dou sth()。这一点很重要,因为它允许您在函数内部修改local\u dict,并且不会对其他调

我对python相当陌生,我想知道局部变量是如何工作的。让我们从一个简单方法的示例开始:

def do_sth():
    local_dict = { 'a': 1, 'b': 2, 'c': 3, ... }
    ...
让我们假设local_dict像一种常量变量一样使用。问题是:每次调用dou sth()时都会创建它,或者创建一次并保存在dou sth()内部的某个地方?

每次调用
dou sth()
。这一点很重要,因为它允许您在函数内部修改
local\u dict
,并且不会对其他调用产生任何影响。解释器不够聪明,无法判断您是否会更改它,特别是因为Python是如此动态,有一些非常迂回的方法可以使它更改

以下是您如何向自己证明词典不断被重新创建的方法:

def print_3():
    print(3)

def do_sth():
    local_dict = {'a': print_3()}

do_sth()
do_sth()
do_sth()
这张照片是3。。。三次

我认为全局变量可以优化这一点,但如果你真的想,那么这个怎么样:

def do_sth():
    return do_sth.local_dict

do_sth.local_dict = {'a': print_3()}

从技术上讲,每个人都可以访问它,但更清楚地知道它属于什么。局部变量总是在函数的范围内创建的。一旦程序计数器退出函数(局部变量的作用域),垃圾收集器就会收集这些数据


您可以使用
dis
模块查看解释器的功能:

def do_sth():
    d = {'a':2, 'b':3}
    print(id(d))


import dis
dis.dis(do_sth)
将打印

  2           0 BUILD_MAP                2
              3 LOAD_CONST               1 (2)
              6 LOAD_CONST               2 ('a')
              9 STORE_MAP           
             10 LOAD_CONST               3 (3)
             13 LOAD_CONST               4 ('b')
             16 STORE_MAP           
             17 STORE_FAST               0 (d)

  3          20 LOAD_GLOBAL              0 (id)
             23 LOAD_FAST                0 (d)
             26 CALL_FUNCTION            1
             29 PRINT_ITEM          
             30 PRINT_NEWLINE       
             31 LOAD_CONST               0 (None)
             34 RETURN_VALUE        

这表明解释器在每次调用函数时都在重建值。

其他答案都是正确的,我只想添加这个

在这种情况下,我宁愿:

constant_dict = { 'a': 1, 'b': 2, 'c': 3, ... }
def do_sth():
    # do something reading constant_dict

do_sth()
但不太可取

def do_sth(local_dict = { 'a': 1, 'b': 2, 'c': 3, ... }):
    # do something reading local_dict

do_sth()
在这两种情况下,python都不必为变量重新分配内存,因为解释器在读取python文件时声明并分配了该变量


如果我错了,请更正。

很容易与
is
操作员进行检查:

def test():
    return {'a': 1, 'b': 2, 'c': 3}

>>> test() is test() #did both produce the same object in memory space?
False
这对于可变对象很有意义,否则陷阱会到处出现

但是,有些值存储为常量,这些值可以使用
dis
查看,因为常量是用字节码加载的:

>>> dis.dis(lambda:1)
  1           0 LOAD_CONST               1 (1)
              3 RETURN_VALUE
>>> dis.dis(lambda:(1,True, 10*1000, "a"))
  1           0 LOAD_CONST               7 ((1, True, 10000, 'a'))
              3 RETURN_VALUE
>>> dis.dis(lambda:[1,2,3]) #list is mutable
  1           0 LOAD_CONST               1 (1)
              3 LOAD_CONST               2 (2)
              6 LOAD_CONST               3 (3)
              9 BUILD_LIST               3
             12 RETURN_VALUE
>>> dis.dis(lambda:{"a":1}) #dict is also mutable
  1           0 LOAD_CONST               1 ('a')
              3 LOAD_CONST               2 (1)
              6 BUILD_MAP                1
              9 RETURN_VALUE

我真的希望你计划扩大这个答案。@TadhgMcDonald Jensen我刚做了,但真的没什么好说的。这是一个非常简单的问题。你们想得太多了。@thebjorn的确,这只是一个小小的乐趣。我不敢相信每个人都投入了这么多心思。@m3diumendi4n请把它放在你拥有的地方(这不是你在Python中应该担心的那种优化)。一般来说,在大多数语言中,没有更改的东西都会被优化为只初始化一次,除非你指示编译器执行其他操作在Python中,解释器通常不会优化任何东西;-)会给出一些答案您错了;-)不要使用dicts作为默认参数(至少不要没有注释)。Python在dicts方面也非常快,在使用全局变量方面也相当慢,所以我不确定您是否会节省时间……我知道使用dicts或list作为默认参数可能会很危险,实际上,dousmth()必须始终在没有参数的情况下调用;-)这并不是说它很危险,但是对于任何在其他地方使用默认参数的人来说,语义通常都是令人惊讶的。如果评论中没有说“…用于记忆…”之类的话,大多数Python程序员都会担心。是的,我也会担心,但我在一些著名的第三方模块源代码中多次看到这一点。特别是在递归或迭代编号等过程中,对树级进行记忆。在使用它进行记忆时,这是正确的做法——但要注意多个线程,并再次使用注释,让下一个人知道你理解了自己在做什么。
>>> dis.dis(lambda:1)
  1           0 LOAD_CONST               1 (1)
              3 RETURN_VALUE
>>> dis.dis(lambda:(1,True, 10*1000, "a"))
  1           0 LOAD_CONST               7 ((1, True, 10000, 'a'))
              3 RETURN_VALUE
>>> dis.dis(lambda:[1,2,3]) #list is mutable
  1           0 LOAD_CONST               1 (1)
              3 LOAD_CONST               2 (2)
              6 LOAD_CONST               3 (3)
              9 BUILD_LIST               3
             12 RETURN_VALUE
>>> dis.dis(lambda:{"a":1}) #dict is also mutable
  1           0 LOAD_CONST               1 ('a')
              3 LOAD_CONST               2 (1)
              6 BUILD_MAP                1
              9 RETURN_VALUE