花了4 5个小时找出来的一个python相关的bug, 大家来讨论一下 - 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
sdjl
V2EX    Python

花了4 5个小时找出来的一个python相关的bug, 大家来讨论一下

  •  
  •   sdjl 2012-12-24 23:36:37 +08:00 4027 次点击
    这是一个创建于 4746 天前的主题,其中的信息可能已经有所发展或是发生改变。
    是这样的, 今天下午写代码时遇到一个非常奇怪的bug, 与我原有对python的认知冲突, 实在不理解,所以花了许多时间才找到这个bug, 下面我把它用简单的方式重现出来, 大家讨论一下

    首先, 在项目文件夹里面有以下几个文件:

    test.py
    model/Model.py
    model/__init__.py
    model/content/__init__.py

    test.py中只有一句话: import model

    然后model/__init__.py 中的内容为:
    print __file__ # 打印当前文件路径
    from Model import ModelData
    import content

    其中print是为了调试看得, 另外两句一句都不能少

    然后model/Model.py文件中的内容如下:
    class Model:
    pass
    class ModelData:
    pass

    声明两个class而已

    最后一个文件 model/content/__init__.py 中的内容如下:
    from .. import ModelData


    整个代码的逻辑就是,test import了model, 而model又import了model/content
    model/content 又 import ModelData, 而这个ModelData是在model/__init__.py中import的

    看起来像是一个循环,其实并不是, 也没有矛盾, 代码能正常运行, 运行test.py文件后输出:
    ***/model/__init__.pyc

    嗯,这是正常的, 然后我们把model/content/__init__.py的内容改为:
    from Model import ModelData
    然后再运行test.py, 会抛出以下异常:
    from Model import ModelData
    ImportError: No module named Model

    嗯,这也是正常的, 因为第二种写法确实是错的

    但是,bug来了, 第二种写法如果是在我这种特殊环境中运行就不正常了,
    我用debian虚拟机写程序, 但是为了代码安全, 我把代码放到mac的文件系统上,然后通过共享文件夹的方式共享给debian系统。

    然后我在debian下运行mac系统的python文件, 就不会抛出异常! 而出现以下的输出:
    ***/model/__init__.pyc
    ***/Model/__init__.pyc

    尼玛, print语句运行了两次, 也就是说model被导入了两次! 并且第一次导入时初始化的数据会被第二次覆盖, 也就是这个特性导致我花了好几个小时来处理这个bug


    也就是说, 如果你像我一样在区分大小写的系统上运行程序, 但是代码放在不区分大小写的系统上, 那么注意了, 像 from ABC import *** 这样的代码, 如果你的ABC和abc分别表示不同的意思, 那么就可能出现应该抛出异常但是没有抛出而引起其它bug的可能
    5 条回复    1970-01-01 08:00:00 +08:00
    wynemo
        1
    wynemo  
       2012-12-25 00:44:23 +08:00
    test.py
    model/Model.py
    model/__init__.py

    其实你要说明问题只要这三个文件 就可以了嘛

    test.py里写from Model from Model 看会不会抛异常

    至于有的系统区分大小写 有的不区分 分别找一个系统 建立一模一样的代码 (比如上面的) 各自跑下 看啥情况
    mrluanma
        2
    mrluanma  
       2012-12-25 02:09:43 +08:00
    正如1楼所言,这是因为Mac的HFS文件系统默认配置是文件名大小写不敏感的。
    sdjl
        3
    sdjl  
    OP
       2012-12-25 21:42:00 +08:00
    @wynemo 嗯 好像是, 昨天被bug搞累了。。。。。

    尝试了, 仅在使用虚拟机且代码放到mac系统里才会出现这个情况
    ledzep2
        4
    ledzep2  
       2012-12-25 21:55:14 +08:00
    大小写从来都是个需要注意的问题....
    ledzep2
        5
    ledzep2  
       2012-12-25 21:55:27 +08:00
    但是这不是python的问题
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     935 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 19:55 PVG 03:55 LAX 11:55 JFK 14:55
    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