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

Python 都有哪些语言坑?

  •  
  •   RTNelo ·
    RTNelo · 2015-12-12 18:57:52 +08:00 · 7476 次点击
    这是一个创建于 3268 天前的主题,其中的信息可能已经有所发展或是发生改变。

    先说个我知道的:

    '''Python 2.7.6'''
    
    In [1]: class Test(object):
       ...:     def test(self):
       ...:         pass
       ...:     
    
    In [2]: a = Test()
    
    In [3]: b = Test()
    
    In [4]: a.test is b.test
    Out[4]: False
    
    In [5]: id(a.test) == id(b.test)
    Out[5]: True
    
    第 1 条附言  ·  2015-12-13 01:19:54 +08:00
    '''Python 2.7.6'''
    
    In [1]: import collections
    
    In [2]: collections.OrderedDict({2: '2', 1: '1'})
    Out[2]: OrderedDict([(1, '1'), (2, '2')])
    
    第 2 条附言  ·  2015-12-13 01:28:51 +08:00
    In [3]: collections.OrderedDict(b=1, a=2)
    Out[3]: OrderedDict([('a', 2), ('b', 1)])
    
    56 条回复    2015-12-16 20:10:49 +08:00
    ihciah
        1
    ihciah  
       2015-12-12 19:13:19 +08:00
    0.1+0.2==0.3 是 False ( js 同
    dqh3000
        2
    dqh3000  
       2015-12-12 19:13:35 +08:00
    这算吗?我好像可以理解

    最大的坑不是 2 和 3 的区别吗?
    ChiangDi
        3
    ChiangDi  
       2015-12-12 19:14:23 +08:00
    lambda 只能写在一行里,绝对无法忍受。
    icedx
        4
    icedx  
       2015-12-12 19:14:26 +08:00
    Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> a = [1, 2]
    >>> id(a)
    38866296
    >>> b = a
    >>> id(b)
    38866296
    >>> c = a[:]
    >>> id(c)
    39037928
    >>> d = list(a)
    >>> id(d)
    37600672
    >>> import copy
    >>> e = copy.copy(a)
    >>> id(e)
    39079008
    >>>
    LINAICAI
        5
    LINAICAI  
       2015-12-12 19:20:33 +08:00
    实在无法理解,相同或者类似互补功能的函数放不同的模块。。。
    Grenadn
        6
    Grenadn  
       2015-12-12 19:21:24 +08:00
    Python 2 字符编码相关的坑吧,都体会过的
    feikaras
        7
    feikaras  
       2015-12-12 19:24:04 +08:00
    @icedx 感觉不算坑啊,算基础知识。

    感觉主要是编码坑和 2 , 3 版本的坑吧。
    chevalier
        8
    chevalier  
       2015-12-12 19:43:46 +08:00
    In [1]: a = float('nan')

    In [2]: print('a is a: ', a is a)
    ('a is a: ', True)

    In [3]: print('a == a: ', a == a)
    ('a == a: ', False)

    亮瞎了
    eclipselu
        9
    eclipselu  
       2015-12-12 19:50:55 +08:00
    congeec
        10
    congeec  
       2015-12-12 20:09:22 +08:00
    楼上说的浮点数相关问题,好多语言都这样,如果不这样实现性能会大打折扣。 list 和 class 的引用可以算俩坑。列表楼上易经说了,类循环引用会造成内存泄漏。看看这个就知道了 https://docs.python.org/3/library/weakref.html 不过其他语言里也有呀。
    wph95
        11
    wph95  
       2015-12-12 20:10:55 +08:00
    python2 的字符串,简直是深坑
    怒转 python3
    congeec
        12
    congeec  
       2015-12-12 20:11:42 +08:00
    还有个比较坑的地方是 os.path.join 和 str.join 用法不一样, str.join 接受 iterable 做参数, os.path.join 可以接受可变参数。。。。。用错也没提示,真坑。
    fwee
        13
    fwee  
       2015-12-12 20:40:43 +08:00
    1. python2 弱类型: 2 >"WTF" => False
    2. 默认参数不是每次都初始化
    3. lambda 只能一行且不能出现 statement
    4. py2 多返回值: a, b = 1,2,3 会报错
    5. StandardError 经常 catch 不到东西,大多数都得上 Exception
    6. 没 switch, 大段 if 真的很丑
    7. 推荐 format 方法来格式化,但是 log 中却还是旧的字符串格式化
    fwee
        14
    fwee  
       2015-12-12 20:41:46 +08:00
    8. urljoin 和预期不同,不能接受多个参数,必须一个个嵌套,而且第一个参数如果格式错误也会返回很奇怪的结果
    felixzhu
        15
    felixzhu  
       2015-12-12 21:07:07 +08:00
    常规开发中主要的坑应该是

    1. 字符集
    2. 2 和 3 的版本问题
    yangtukun1412
        16
    yangtukun1412  
       2015-12-12 21:07:10 +08:00
    >>> def test(a=[]):
    ... a.append(1)
    ... return a
    ...
    >>> test()
    [1]
    >>> test()
    [1, 1]
    quietin
        17
    quietin  
       2015-12-12 21:14:36 +08:00
    列表解析里的变量作用域外泄
    Changxu
        18
    Changxu  
       2015-12-12 22:00:08 +08:00
    这感觉不算坑啊,只能算语法特性
    Pastsong
        19
    Pastsong  
       2015-12-12 22:10:19 +08:00
    fy
        20
    fy  
       2015-12-12 22:37:06 +08:00
    坑都在 py2 ,郁闷的是 py2/3 的分别本身也是个坑,向下兼容很烦人。
    ksc010
        21
    ksc010  
       2015-12-12 22:38:38 +08:00
    is 和 == 本身就不是一个意思
    is 比较的是是否是同一个"对象"
    ==比较的是否是相同的“值”
    oaix
        22
    oaix  
       2015-12-12 23:16:40 +08:00
    是问 python2 还是 python3 ?
    Hyperion
        23
    Hyperion  
       2015-12-12 23:26:54 +08:00   ❤️ 1
    小数是 IEEE754 的锅, JavaScript/Python 表示不背。
    des
        24
    des  
       2015-12-13 00:00:49 +08:00
    @chevalier NaN 本来就不等于任何东西,包括他自己,你是头一回知道吗?
    semut
        25
    semut  
       2015-12-13 00:03:09 +08:00
    @chevalier nan 是指 not a number ,所以不能说两个不是数的东西一定会相等啊
    icedx
        26
    icedx  
       2015-12-13 00:22:02 +08:00
    @feikaras 是 features
    xuboying
        27
    xuboying  
       2015-12-13 00:24:54 +08:00
    lambda 一行+1
    Yinz
        28
    Yinz  
       2015-12-13 00:39:21 +08:00
    In [1]: a = 123456789012345678901234567890123456789012345678901234567890

    In [2]: a /= 2

    In [3]: a
    Out[3]: 61728394506172839450617283945061728394506172839450617283945L

    In [4]: a % 2 == 0
    Out[4]: False

    In [5]: from __future__ import division

    In [6]: a = 123456789012345678901234567890123456789012345678901234567890

    In [7]: a /= 2

    In [8]: a
    Out[8]: 6.172839450617284e+58

    In [9]: a % 2 == 0
    Out[9]: True

    版本 Python 2.7.10

    导入 future 的 division 后的灵异事件,之前遇到的
    RTNelo
        29
    RTNelo  
    OP
       2015-12-13 00:53:28 +08:00
    @Yinz true division 先把操作数转换成 float 再运用除法...所以这种情况是因为 float 损失精度出现的?
    RTNelo
        30
    RTNelo  
    OP
       2015-12-13 01:07:26 +08:00
    另外好多字符编码问题是“ decode 参数是用 GB2312 、 GBK 还是 GB18030 ?”的问题...
    Yinz
        31
    Yinz  
       2015-12-13 01:08:01 +08:00   ❤️ 1
    @RTNelo 是的的确就是导入 division 后自动转 float 的精度损失问题,解决方法也是有的,强制高精度计算就行了。不过这个主要是反直觉的坑,当时我逐步调试找了有一会的。
    ipconfiger
        32
    ipconfiger  
       2015-12-13 01:08:07 +08:00
    慢!~~~~~~~~~~~~~~~~~
    RTNelo
        33
    RTNelo  
    OP
       2015-12-13 01:09:39 +08:00
    @ksc010 我举的那个例子重点根本不是运算符。
    RTNelo
        34
    RTNelo  
    OP
       2015-12-13 01:13:29 +08:00
    @Yinz 强制高精度计算?是用 Decimal 吗?
    Yinz
        35
    Yinz  
       2015-12-13 01:14:56 +08:00
    @RTNelo 对,其中一个数转成 Decimal 实例就行了,计算完再转回标准类型
    congeec
        36
    congeec  
       2015-12-13 08:38:28 +08:00
    这个应该是你想要的答案: Python 的 16 个“坑”
    http://saebbs.com/forum.php?mod=viewthread&tid=38016&page=1&extra=
    CRVV
        37
    CRVV  
       2015-12-13 12:39:09 +08:00   ❤️ 1
    @Yinz @RTNelo
    from __future__ import division
    这一行是引入 Python3 的除法运算符
    '/' 是浮点数除法
    '//' 是整数除法

    请搞清楚自己写的每一行代码的意思
    RTNelo
        38
    RTNelo  
    OP
       2015-12-13 13:03:15 +08:00
    @CRVV 那还真是抱歉,所有对语言坑的吐槽都可以用一句“请搞清楚自己写的每一行代码的意思”顶回去。
    edsgerlin
        39
    edsgerlin  
       2015-12-13 13:04:34 +08:00
    @ChiangDi lambda 要是能写多行,我就想把 Python 当成函数式语言用了……真可惜。
    dawncold
        40
    dawncold  
       2015-12-13 14:45:46 +08:00
    generator 只能遍历一次

    groupby 要先自己排好序?
    Yinz
        41
    Yinz  
       2015-12-13 14:55:02 +08:00
    @CRVV 说了反直觉看不懂?
    wizardoz
        42
    wizardoz  
       2015-12-13 16:14:50 +08:00
    @wph95 转了 3 以后发现很多习惯库都不支持 3 ,甚至连替代品都没有,这个坑比 2 的字符坑还要大
    CRVV
        43
    CRVV  
       2015-12-13 16:41:11 +08:00   ❤️ 1
    @Yinz
    随意找一个学过数学的人来判断,如果 '/' 除法运算符, 3 / 2 = 1.5 是非常正常的事情
    3 / 2 = 1 才是反直觉
    这里显然是为了和直觉一致,在 Python 3 里改了
    CRVV
        44
    CRVV  
       2015-12-13 16:47:31 +08:00   ❤️ 1
    @RTNelo
    这种事情有一个限度
    比如我绝不会用“请搞清楚自己写的每一行代码的意思”来说你在最上面写的关于 id 事情

    你们都能想到用“转成 Decimal 实例”这么奇怪的方法来调用 Python 的整数运算了,明显是没看过 Python3 和 Python2 的差别
    而这个除法运算符的差别是 https://docs.python.org/3/howto/pyporting.html 里面讲的第一个 2 和 3 的差别
    丝毫不看文档,又要 from __future__ import xxx ,出错了还怪语言
    那我觉得吐槽你们不懂自己写的代码并没有错
    judasnow
        45
    judasnow  
       2015-12-13 17:10:57 +08:00
    x = 1,
    # x = (1,)
    Yinz
        46
    Yinz  
       2015-12-13 17:19:54 +08:00   ❤️ 1
    @CRVV 你好,我想你并没有看懂我一开始表达的意思。 Python2 在引入 future 的 division 后,即使是对超长整数进行除法运算,也会使运算结果被转换为使用科学计数法储存的 float 类型,导致精度丢失。其中,精度丢失是我认为的反直觉之处。

    对于你回复 @RTNelo 说我们不看文档怪语言这句话,我认为我们之间存在较大理解分歧,我不准备展开辩论。
    RTNelo
        47
    RTNelo  
    OP
       2015-12-13 17:21:33 +08:00   ❤️ 1
    @CRVV
    PEP238 第二段
    ```
    We propose to fix this by introducing different operators for
    different operations: x/y to return a reasonable approximation of
    the mathematical result of the division ("true division"), x//y to
    return the floor ("floor division").
    ```
    ”/“相对于”//“这个"floor division"被称为"true division",但是这里因为精度损失导致"/"不再是"true division"了。我用 Decimal 来实现更精确的"true division"很奇怪?用"//"来实现"true division"的你连 floor division 和 true division 都分不清还来指责我”明显没看过 Python3 和 Python2 的差别“?

    另外,不要觉得除了你就没人看语言文档了。
    RTNelo
        48
    RTNelo  
    OP
       2015-12-13 17:25:42 +08:00
    @CRVV 对于一个学过数学的人来说,你不觉得 4 * n / 2 ( n 为整数)的结果不是个偶数是个很反直觉的事吗?
    fine
        49
    fine  
       2015-12-13 20:13:30 +08:00
    函数默认参数
    Z1076
        50
    Z1076  
       2015-12-14 03:50:34 +08:00
    python3.4 旧版本有一个 bug 用 apache 部署 django 会导致找不到 mod_wsgi 模块………… 旧的版本和 3.4.4 都没有问题┻━┻︵╰(‵□′)╯︵┻━┻
    jezal
        51
    jezal  
       2015-12-14 09:28:56 +08:00
    编码、时区,我遇到的两个坑。
    esile
        52
    esile  
       2015-12-14 17:06:08 +08:00 via iPhone
    编码
    编码
    编码
    要说 3 遍
    bingoqiu
        53
    bingoqiu  
       2015-12-14 17:10:50 +08:00
    a = b, c = [1, 2]
    mulog
        54
    mulog  
       2015-12-15 12:31:05 +08:00
    我觉得真的坑的也就是编码 和 py2/py3 的兼容性
    哦对了还有 list comprehension 的「作用域泄漏」,虽然我没遇过, 当时看到它真是 wtf.. 不过 python3 已经修复了。
    mingyun
        55
    mingyun  
       2015-12-15 21:27:07 +08:00
    >>> a=1
    >>> id(a)
    31056200L
    >>>b=1
    >>> id(b)
    31056200L
    >>> id(c)
    35743896L
    >>> d=257
    >>> id(d)
    35743872L
    shutongxinq
        56
    shutongxinq  
       2015-12-16 20:10:49 +08:00 via iPhone
    @CRVV 任何一个 python3 的 tutorial 里面都会着重讲两个 division 的区别吧...这真不是 python 的问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1032 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 19:25 · PVG 03:25 · LAX 11:25 · JFK 14:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.