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
itlynn
V2EX  ›  Python

Python 的一个坑(元组)? or (多重赋值)?

  •  
  •   itlynn · 2016-04-17 23:39:50 +08:00 · 4866 次点击
    这是一个创建于 3171 天前的主题,其中的信息可能已经有所发展或是发生改变。
    想问问各位 Python 大牛,这段代码我该如何理解?
    代码如下:

    (a,b) = (1,2)
    print id((a,b))
    (a,b) = ("string",2)
    print id((a,b))
    print type((a,b))

    问题:在各种环境测试下,发现有时候两个 id()返回值相同,有时又不同。希望大牛给分析下
    12 条回复    2016-04-18 19:31:12 +08:00
    wowpanda
        1
    wowpanda  
       2016-04-17 23:48:54 +08:00 via Android
    楼主能贴出来在那些环境相同,哪些不同吗
    Abirdcfly
        2
    Abirdcfly  
       2016-04-17 23:54:31 +08:00
    没那么复杂
    >>> (a,b) = (1,2)
    >>> print id((a,b))
    140320109531008
    >>> (a,b) = ("string",2)
    >>> print id((a,b))
    140320109530936
    上面的不一样.
    >>> (a,b) = (1,2);print id((a,b));(a,b) = ("string",2);print id((a,b))
    140320109531080
    140320109531080
    下面的一样.

    为什么我就不清楚了..只能解释为解释器的优化..
    我之前问过一个类似的...回答那哥们也是从解释器优化说的..字节码显示是优化过了..为什么就不清楚了..


    [When the Python interpreter deals with a .py file, is it different from dealing with a single statement?]( http://stackoverflow.com/questions/36474782/when-the-python-interpreter-deals-with-a-py-file-is-it-different-from-dealing)

    有哪位大神路过看看呗?
    Abirdcfly
        3
    Abirdcfly  
       2016-04-17 23:55:01 +08:00
    @wowpanda 求解释
    itlynn
        4
    itlynn  
    OP
       2016-04-18 00:03:46 +08:00
    @wowpanda

    windows 下:
    ulipay , sublime, 终端 运行 py 文件, 结果为同一个 id
    但是在终端下手工输入返回不是同一个 id
    wartime
        5
    wartime  
       2016-04-18 00:05:17 +08:00   ❤️ 1
    id(...)
    id(object) -> integer

    Return the identity of an object. This is guaranteed to be unique among
    simultaneously existing objects. (Hint: it's the object's memory address.)

    (a, b) 实际上是临时分配的一个变量,由于没有引用可能马上释放。
    (1, 2) 和 ('string', 2) 如果凑巧在相同位置,看上去 id 值一样,实际上之前的已经释放,内容已经改变。

    c = (a,b) = (1,2)
    print id(c)
    d = (a,b) = ("string",2)
    print id(d)

    在 c 和 d 的值不变的情况下, id(c) id(d)值不变 (tuple 是 immutable)
    glennq
        6
    glennq  
       2016-04-18 00:08:56 +08:00
    一样是巧合,不一样才正常
    kkhaike
        7
    kkhaike  
       2016-04-18 00:11:50 +08:00
    @wartime 这个解释是对的
    itlynn
        8
    itlynn  
    OP
       2016-04-18 00:18:36 +08:00
    @wartime @Abirdcfly @glennq @wowpanda @kkhaike
    感谢各位,我的理解是
    (a,b) = (1,2) #这里进行了一次多重赋值, a = 1;b = 2
    print id((a,b)) #由于(a,b)并没有赋值给一个对象,只是一个临时的存储 a,b 的元组,所以系统 会 or 可能会 将之销毁
    (a,b) = ("string",2) #将 a 重新赋值,则重新创建一个字符串对象并指向该内存地址
    print id((a,b)) #所以此处并不会与上的 id((a,b))相同,如果相同纯属偶然?
    不知这样理解合理吗?
    wartime
        9
    wartime  
       2016-04-18 00:31:09 +08:00   ❤️ 1
    @itlynn 对,而且 id((a,b))是取元组的 id ,和 a 、 b 的内存地址无关。
    fy
        10
    fy  
       2016-04-18 01:08:10 +08:00   ❤️ 1
    楼主啊,你以为多重赋值左边的东西真的是元组??

    a, b = (a, b) = [a, b] = 1, 2

    这三种左侧的字节码是一模一样的,而且跟元组没有任何关系。

    你后来 id((a,b)) 这才是建立了一个元组
    jiang42
        11
    jiang42  
       2016-04-18 01:52:38 +08:00 via iPhone   ❤️ 1
    @wartime 补充一点, id 的实现方式与 Python 的实现方式有关, CPython 用的是内存地址。
    @itlynn
    itlynn
        12
    itlynn  
    OP
       2016-04-18 19:31:12 +08:00
    @fy
    @jiang42 谢谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5755 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 03:34 · PVG 11:34 · LAX 19:34 · JFK 22:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.