# 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
Hualin
V2EX    Python

# python 学习:各种类之间循环引用,以及参数传递

  •  
  •   Hualin 2013-05-07 19:03:06 +08:00 4515 次点击
    这是一个创建于 4613 天前的主题,其中的信息可能已经有所发展或是发生改变。
    今天做了个实验,代码是这样的:

    === data.py ===

    class Data:
    def __init__(self):
    self.base_x = 123

    === plugin.py ===

    class Plugin:
    def __init__(self, para, data):
    self.para = para
    self.data = data
    self.data.para = para

    def remove(self):
    del self.data.para

    === main.py ===

    from data import Data
    from plugin import Plugin

    dd = Data()
    pp = Plugin(999, dd)

    print dd.base_x
    print dd.para

    pp.remove()
    print dd.para

    == 输出结果是这样的:==
    123
    999

    Traceback (most recent call last):

    File "C:\test\main.py", line 11, in <module>
    print dd.para
    AttributeError: Data instance has no attribute 'para'
    [Finished in 0.1s with exit code 1]

    那么 Plugin 的对象 pp 的初始化函数参数 data,实际上是 Data 类 dd 的实际指针。所以我执行 del self.data.para 后 dd 也就没有这个属性了。

    这样的话 pp.data 实际和 main 中的 dd 指向的都是同一个对象。

    请问各位 v2exer 们,有关 python 传递参数这种对象循环传递,以及函数参数是引用还是拷贝的知识在哪里能有介绍?

    欢迎讨论
    10 条回复    1970-01-01 08:00:00 +08:00
    raquelken
        1
    raquelken  
       2013-05-08 16:25:45 +08:00   1
    既不是引用也不是拷贝,参数名字就真的只是名字而已,关键是你例子里面的pp.data和main的dd是同一个对象,而且Data是可修改的(mutable)
    所以你可以修改pp.data的para属性,也就是dd的para属性
    http://effbot.org/zone/python-objects.htm
    Idiosyncratic
        2
    Idiosyncratic  
       2013-05-09 15:46:53 +08:00
    @raquelken 我感觉,lz想问的是参数传递的方式而不是object的底层实现啊。。,

    其实按照那片文章的意思,所有的名字其实都是一种 对于对象的指针(比喻而已,暂时想不到更贴切的),那么所有的参数传递应该都可以视为引用传递
    thedevil5032
        3
    thedevil5032  
       2013-05-09 16:24:11 +08:00
    函数参数是引用还是拷贝的知识在哪里能有介绍?

    其实这个问题的关键在于,你的参数是什么类型的。(貌似是这样的)

    http://docs.python.org/2/library/copy.html

    ####
    a = 1
    b = 1
    id(a) == id(b)

    # 自己的一点理解
    # 通常赋值一个常量对象,实际上是把一个常量名和内存中的一个值联系起来了。
    # 但是如果是集合型的对象(list,dict等,具体参照上面的链接),则有时会是复制,有时则是“链接”。
    raquelken
        4
    raquelken  
       2013-05-09 16:48:02 +08:00
    @Idiosyncratic 如果是引用的话,如何用python实现这个呢?
    void addone(int &in) {
    in ++;
    }

    int main(int argc, char const *argv[])
    {
    int in = 1;
    addone(in);
    return 0;
    }
    yuelang85
        5
    yuelang85  
       2013-05-09 17:23:59 +08:00
    可以使用id函数来测试。

    python中,没有传递值,任何时候都是传递指针。
    >>> def a(x, y):
    ..._____print id(x), id(y)
    ..._____x.append(1)
    ..._____y+=1
    ..._____print id(x), id(y)
    ...

    >>> x = []
    >>> y = 0

    >>> id(x), id(y)
    (4547969608, 140234989831872)

    >>> a(x, y)
    4547969608 140234989831872
    4547969608 140234989831848
    >>>


    int,str是不可变对象,自身不能改变,所以修改的时候会产生新对象。而list,dict等可以修改自身
    Idiosyncratic
        6
    Idiosyncratic  
       2013-05-09 17:42:01 +08:00
    @raquelken 嗯,那也是,所以说,我觉得那片文章讲的只是python底层object和name的如何绑定的关系,并没有解释参数传递的方式;具体在参数传递上应该还是和其他面向对象语言很像,要看对象的类型,值类型就值传递(int,或是C#里的struct),引用类型就引用传递;
    以上只是猜测哈,我没仔细研究过python,不过感觉用着像是这么回事
    timonwong
        7
    timonwong  
       2013-05-09 19:48:07 +08:00
    @Idiosyncratic
    传递方式与java类似,属于“值传递"(只是python没有primitive types,所有的值传递传递的都是**对象的引用**)
    yuelang85
        8
    yuelang85  
       2013-05-09 19:51:34 +08:00
    @Idiosyncratic

    看看我的回复。。。。

    python根本就没有值传递。

    如果你想传递值,只能生成一个新对象
    Idiosyncratic
        9
    Idiosyncratic  
       2013-05-09 20:55:57 +08:00
    @yuelang85 嗯,学习了,试了一下@yuelang85的测试,的确是这样的。多谢!!
    yuelang85
        10
    yuelang85  
       2013-05-09 21:04:47 +08:00
    @Idiosyncratic 客气。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3569 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 04:19 PVG 12:19 LAX 20:19 JFK 23:19
    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