入门问题求解答~有关Python中函数传值的问题 - V2EX
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
davidli

入门问题求解答~有关Python中函数传值的问题

  •  
  •   davidli
    hmli 2013 年 6 月 11 日 4718 次点击
    这是一个创建于 4701 天前的主题,其中的信息可能已经有所发展或是发生改变。
    新人,一直在潜水,第一次提问。
    以前学JAVA,又学了点JS,最近学Python.
    了解到Python中函数如果要使用函数外某变量,那它只是将其值复制一份传入,而非直接将此变量引用。
    这样, 如果我想用一个函数对函数外的值进行修改,应该怎么做?

    比如 已有a=1, b=2,我想写一个swap(a,b), 让这两个数交换其值, 应该怎么写?

    得知可以用global变量,但一是灵活性太差,二是感觉这么小的问题就用到了global,有点杀鸡用牛刀的意味。

    所以请问在Python有没有比较合适的解决此问题的方法?
    11 条回复    1970-01-01 08:00:00 +08:00
    wwwjfy
        1
    wwwjfy  
       2013 年 6 月 11 日   2
    1. a, b = b, a

    2. 函数返回值重新赋值

    3. 包在字典或者列表之类的传引用的进去

    具体情况具体分析
    davidli
        2
    davidli  
    OP
       2013 年 6 月 11 日
    @wwwjfy
    a,b = b,a !!!
    还能这么用!!
    用惯了JAVA死板的语法,一时半会适应不能
    但请问这样为什么不会出现a =b, b=b的错误?
    wwwjfy
        3
    wwwjfy  
       2013 年 6 月 11 日
    @davidli 没研究那么深

    python本来就是支持这种多赋值的,也没有执行顺序的差别,不会出现那种错误...

    其实a, b是(a, b), c = a, b ==> c = (a, b)

    充其量算是语法糖,跟语言本质没什么关系
    swulling
        4
    swulling  
       2013 年 6 月 11 日   1
    Python分可变对象和不可变对象,可变对象你是不能用swap()来修改其值得
    swulling
        5
    swulling  
       2013 年 6 月 11 日
    突然发现回答写错了。。可变对象 ---> 不可变对象

    不过应该都知道<_<
    ruoyu0088
        6
    ruoyu0088  
       2013 年 6 月 11 日   2
    a, b = b, a
    这句执行时,先运行b, a, 得到一个tuple对象,然后由于等号左边有两个名字,因此又将tuple对象打开。相当于执行以下两句:
    t = b, a
    a, b = t
    firstway
        7
    firstway  
       2013 年 6 月 11 日
    我的理解是,lz对swap(a,b)只是一个举例,lz问题的核心(正如swulling所说)其实就是“可变对象和不可变对象”的理解。lz可以找找“可变对象和不可变对象”相关文章看看。
    firstway
        8
    firstway  
       2013 年 6 月 11 日
    对于不可变对象,比如数值类型,函数传递都是是值传递,也就是复制一份,函数内任何修改对函数外没有影响,除了global。
    如果是可变对象,比如list,可以理解为引用传递,函数内的In-Place Changes就会修改引用本身的内容。比如:
    def my_add(L):
    L[0] = L[0]+100
    a = [8,9,10]
    my_add(a)
    print(a) ## a = [108,9,10]
    y0
        9
    y0  
       2013 年 6 月 12 日
    “用一个函数对函数外的值进行修改” 这种行为本来就应该避免。
    好的 “函数” 应该是不保存任何状态,每次运行结果都一样的。
    运行结果不一样的,那叫指令而不是函数,需要保存状态的话用闭包。

    你需要改变的是这种思路而不是找个办法修改外部的值。

    实在有必要的话,让函数返回需要的值,再 unpack. 和 swap 类似。比如

    def h(a,b,c):
    ....xxxxxxxxxxx
    ....xxxxxxxxxxx
    ....return new_a, new_b, new_c

    a, b, c = h(a, b, c)
    glasslion
        10
    glasslion  
       2013 年 6 月 21 日
    @firstway 不可变对象还是应用传递,不会发生复制。
    itfanr
        11
    itfanr  
       2014 年 2 月 15 日
    楼主的疑惑和我想的也是完全一样,我通过以下的回复渐渐明白了。python是把数字上面挂变量标签,不是往变量盒子里面放数据,和C/JAVA完全不同的。

    @y0 "用一个函数对函数外的值进行修改" C++等语言,只能传地址进去。。。。不过python就应该发挥它的长处
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2495 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 55ms UTC 01:15 PVG 09:15 LAX 18:15 JFK 21:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86