请问python有没有局部变量和全局变量的概念

kainme 2018-04-17 03:12:34
从书上遇到个问题如下:

目的 :函数 buggy() 在每次调用时,添加参数 arg 到一个空的列表 result ,然后打印输出一个单值列表

>>> def buggy(arg, result=[]):
... result.append(arg)
... print(result)
...
>>> buggy('a')
['a']
>>> buggy('b')
['a', 'b']

如果写成下面的样子就会解决刚才的问题:
>>> def works(arg):
... result = []
... result.append(arg)
... return result
...
>>> works('a')
['a']
>>> works('b')
['b']

然后我执行了 result=[] ,然后再分别调用,发现并不影响 这两个函数里的result值

有两个问题:

1) 第一个函数,每次调用都会初始化result函数不是吗?(我按C的方式理解的)为什么会一直保留原有的内容。

2)执行了result=[] 不影响两个函数里的result,那函数里的result是以什么形式保存的,怎么做到不影响的呢,麻烦大佬给解答一下。。感谢
...全文
490 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
kainme 2018-04-18
  • 打赏
  • 举报
回复
引用 4 楼 hbu_pig 的回复:
因为default value只初始化一次。列表又正好是可变的。 官网是这么解释的 Why are default values shared between objects? This type of bug commonly bites neophyte programmers. Consider this function:
def foo(mydict={}):  # Danger: shared reference to one dict for all calls
    ... compute something ...
    mydict[key] = value
    return mydict
The first time you call this function, mydict contains a single item. The second time, mydict contains two items because when foo() begins executing, mydict starts out with an item already in it. It is often expected that a function call creates new objects for default values. This is not what happens. Default values are created exactly once, when the function is defined. If that object is changed, like the dictionary in this example, subsequent calls to the function will refer to this changed object. By definition, immutable objects such as numbers, strings, tuples, and None, are safe from change. Changes to mutable objects such as dictionaries, lists, and class instances can lead to confusion. Because of this feature, it is good programming practice to not use mutable objects as default values. Instead, use None as the default value and inside the function, check if the parameter is None and create a new list/dictionary/whatever if it is. For example, don’t write:
def foo(mydict={}):
    ...
but:
def foo(mydict=None):
    if mydict is None:
        mydict = {}  # create a new dict for local namespace
This feature can be useful. When you have a function that’s time-consuming to compute, a common technique is to cache the parameters and the resulting value of each call to the function, and return the cached value if the same value is requested again. This is called “memoizing”, and can be implemented like this:
# Callers will never provide a third parameter for this function.
def expensive(arg1, arg2, _cache={}):
    if (arg1, arg2) in _cache:
        return _cache[(arg1, arg2)]

    # Calculate the value
    result = ... expensive computation ...
    _cache[(arg1, arg2)] = result           # Store result in the cache
    return result
You could use a global variable containing a dictionary instead of the default value; it’s a matter of taste.
感谢,解释的很明白
kainme 2018-04-18
  • 打赏
  • 举报
回复
引用 5 楼 oyljerry 的回复:
主要还是python中list做默认参数这里有点恶心。 https://www.zhihu.com/question/21924859
谢谢,这和我的问题一样,看了看回答,感觉能理解一些了,但还是模糊。留作历史遗留问题以后学的深入了在回来看看
oyljerry 2018-04-17
  • 打赏
  • 举报
回复
主要还是python中list做默认参数这里有点恶心。 https://www.zhihu.com/question/21924859
欢乐的小猪 2018-04-17
  • 打赏
  • 举报
回复
因为default value只初始化一次。列表又正好是可变的。 官网是这么解释的 Why are default values shared between objects? This type of bug commonly bites neophyte programmers. Consider this function:
def foo(mydict={}):  # Danger: shared reference to one dict for all calls
    ... compute something ...
    mydict[key] = value
    return mydict
The first time you call this function, mydict contains a single item. The second time, mydict contains two items because when foo() begins executing, mydict starts out with an item already in it. It is often expected that a function call creates new objects for default values. This is not what happens. Default values are created exactly once, when the function is defined. If that object is changed, like the dictionary in this example, subsequent calls to the function will refer to this changed object. By definition, immutable objects such as numbers, strings, tuples, and None, are safe from change. Changes to mutable objects such as dictionaries, lists, and class instances can lead to confusion. Because of this feature, it is good programming practice to not use mutable objects as default values. Instead, use None as the default value and inside the function, check if the parameter is None and create a new list/dictionary/whatever if it is. For example, don’t write:
def foo(mydict={}):
    ...
but:
def foo(mydict=None):
    if mydict is None:
        mydict = {}  # create a new dict for local namespace
This feature can be useful. When you have a function that’s time-consuming to compute, a common technique is to cache the parameters and the resulting value of each call to the function, and return the cached value if the same value is requested again. This is called “memoizing”, and can be implemented like this:
# Callers will never provide a third parameter for this function.
def expensive(arg1, arg2, _cache={}):
    if (arg1, arg2) in _cache:
        return _cache[(arg1, arg2)]

    # Calculate the value
    result = ... expensive computation ...
    _cache[(arg1, arg2)] = result           # Store result in the cache
    return result
You could use a global variable containing a dictionary instead of the default value; it’s a matter of taste.
kainme 2018-04-17
  • 打赏
  • 举报
回复
我做了实验,关于是否初始化 >>> def nonbuggy(arg, result=None): ... print(result) ... if result is None: ... result=[] ... print(result) ... >>> nonbuggy('a') None [] >>> nonbuggy('b') None [] 可以看到每次result都会被初始化为None。 >>> def buggy(arg, result=[]): ... print(result) ... result.append(arg) ... return result ... >>> buggy('a') [] ['a'] >>> buggy('b') ['a'] ['a', 'b'] >>> buggy('v') ['a', 'b'] ['a', 'b', 'v'] 而这个函数就没有初始化。同样是result=[]/None为什么一个就可以另一个就不行呢
kainme 2018-04-17
  • 打赏
  • 举报
回复
请问,有没有方法可以直接取出某个函数里的result
kainme 2018-04-17
  • 打赏
  • 举报
回复
可能我第一个问题理解的有问题。 第一个result[]应该只是一个参数,并没有初始化。

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧