Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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_Function Calls_Timeit - Fatal编程技术网

python函数中的变量是否在每次函数调用时重新初始化?

python函数中的变量是否在每次函数调用时重新初始化?,python,function-calls,timeit,Python,Function Calls,Timeit,假设我有两个函数 def myfunction1(number): biglist = [1,2,3,4,5,6,7,8,9] print number*biglist biglist = [1,2,3,4,5,6,7,8,9] def myfunction2(number, biglist): print number*biglist 我用ipython的魔法%timeit: In [5]: %timeit myfunction2(number, bigl

假设我有两个函数

def myfunction1(number):

    biglist = [1,2,3,4,5,6,7,8,9]

    print number*biglist


biglist = [1,2,3,4,5,6,7,8,9]

def myfunction2(number, biglist):

    print number*biglist
我用ipython的魔法%timeit:

In [5]: %timeit myfunction2(number, biglist)
1000000 loops, best of 3: 607 ns per loop

In [6]: %timeit myfunction1(number)
1000000 loops, best of 3: 841 ns per loop
这是否意味着每次调用myfunction1时都会重新声明
biglist
变量?我猜想在第一次函数调用之后,Python会以某种方式将
biglist
变量存储在函数中,这样它就不必在每次调用函数时都重新初始化列表


我不知道Python的内部工作原理,所以我只是在猜测。有人能解释一下到底发生了什么吗?

是的。。它在myfunction1的作用域内,在myfunction2中,它在全局作用域内,直到程序结束才会结束。一旦myfunction1完成,与之关联的任何变量都将被标记为不可访问。每次调用都只会在其作用域中创建一个新的变量


--Sai

如果不进行一些非常复杂的分析,Python就无法执行您的建议。如果我在解释器中键入两次
x=3
,那么赋值语句就是赋值语句,我希望在键入之后,无论我在其间对x做了什么,x都是3。。。这真的没什么不同

举例来说,该函数很容易实现

def myfunction1(number):
    biglist = [1,2,3,4,5,6,7,8,9]
    biglist = number*biglist
    print biglist
在这种情况下,您希望重新分配biglist


这当然忽略了一个事实,即每次调用biglist都是一个不同的变量-您可以让这个func同时在两个线程上执行,它们将是不相关的

Python必须在myfunction1()的每个条目上创建一个新的列表,并将其分配给“biglist”

在myfunction2()中,传递对全局作用域“biglist”的引用,因此不需要进行复制

两者之间还有其他微妙的区别。传入该引用会使全局数据受到(可能不需要的)干扰:

>>> biglist = [ 1,2,3,4,5,6,7,8,9 ]
>>> def myfunction3(mylist):
...     mylist[2] = 99
...
>>> biglist
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> myfunction3(biglist)
>>> biglist
[1, 2, 99, 4, 5, 6, 7, 8, 9]
…然而,在函数范围中声明它意味着每次都会重新创建它。例如:

>>> def myfunction4():
...     mylist = [ 1,2,3,4,5 ]
...     print mylist
...     mylist[2] = 99
...
>>> myfunction4()
[1, 2, 3, 4, 5]
>>> myfunction4()
[1, 2, 3, 4, 5]
每次调用该函数时,您都有一份新的、干净的、未经修改的列表副本可供使用

那么,你如何做到两全其美呢?试试这个:

>>> def myfunction5():
...     mylist = biglist+[] # Make a private copy
...     mylist[4] = 99
...
>>> biglist
[1, 2, 99, 4, 5, 6, 7, 8, 9]
>>> myfunction5()
>>> biglist
[1, 2, 99, 4, 5, 6, 7, 8, 9]
您可以看到全局作用域列表没有改变。基于此方法,您的新功能将是:

def myfunction1a(number):
    mylist = biglist+[] # Copy-safe version
    print number*mylist

使用您的基准计时与此相比如何?我知道,在这种情况下,您实际上并没有修改函数中的“biglist”,但如果您必须共享全局数据,那么使用它并不是一个不好的范例,而且列表只从头构建一次(然后复制)这一事实可能会带来一些性能改进。

global并不意味着全局。你给了我一段代码,我参考过。在功能范围之外。请注意我的功能1。Wrt到外部作用域它不需要。没有真正标记为不可访问。无聊的旧ref-counting GC负责清理(至少在cpython中)使用
timeit
的全部目的是计时执行,就像它只运行一次一样!我不太明白。在本例中,这是否导致我对timeit的使用错误?myfunction1a(number)函数的速度实际上与myfunction1相同,但正如您所示,它比其他函数更安全。