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 · 4201 次点击
    这是一个创建于 4243 天前的主题,其中的信息可能已经有所发展或是发生改变。
    今天做了个实验,代码是这样的:

    === 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   ·   实用小工具   ·   1526 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 17:01 · PVG 01:01 · LAX 09:01 · JFK 12:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.