V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
palmers
V2EX  ›  Python

关于 Python 的默认参数,有一个疑惑,请教大家![python3]

  •  
  •   palmers · 2017-01-19 16:07:31 +08:00 · 2442 次点击
    这是一个创建于 2864 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码如下:

    def fun(l=None):
        if l is None:
            l = []
        l.append('append content')
        return l
    

    这里当执行 l = [] 是不是就代表 l 已经指向了 一个空 list 了, 那不是同样会出现默认参数的记忆效果?

    我想这里很有可能是我对 python 内存分配的原理不懂, 烦请大家帮我解释下, 谢谢大家啦!!

    4 条回复    2017-01-20 16:47:29 +08:00
    kindjeff
        2
    kindjeff  
       2017-01-19 16:22:08 +08:00 via iPhone
    当然不会记忆啊,你试试这个
    a=[]
    b=[]
    a.append(1)
    这个时候 b 是[1]吗?
    ipwx
        3
    ipwx  
       2017-01-19 16:38:47 +08:00
    Python 语言设计的一个规定,参数的默认值是对象而非一个表达式,不会每次重新执行,所以你在默认参数写 l=[] 才会导致 mutable 。

    C++ 的规定正好相反,参数的默认值是一个表达式而非一个对象,每次调用都会重新执行这个表达式。
    aragakiiyui
        4
    aragakiiyui  
       2017-01-20 16:47:29 +08:00
    因为函数在 python 中也是一个对象,比如你举例的 fun 函数, func.__defaults__这个属性记录了函数的默认值 tuple ,你这个例子里面,这个 tuple 是(None, )。 假如你默认值指定了一个可变对象,比如空列表。 那么这个 tuple 里面存的值会是([], )。 这样就会导致你在代码中改变这个默认参数的时候(比如往这个列表中加了个元素 10 ),会影响 func.__defaults__相应的值---变成了([10], )。

    所以要避免这种情况,函数的默认参数最好指定为不可变的对象。

    你在函数体中进行 l = [], 等于将 l 这个变量名绑定了新的[], 这样对 func.__defaults__不会产生任何影响。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2678 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 12:15 · PVG 20:15 · LAX 04:15 · JFK 07:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.