• python __future__ package的几个特性


    我学习python过程, 和学习其它编程知识一样, 不是先读大部头书系统学习, 而是看博客和直接实践, 慢慢将这些知识点连成线, 再扩展到面. 这个过程缺点和优点都很明显. 缺点是, 有些知识点可能因为一直没有机会碰到, 就一直是盲点, 另外从点到面过程较长. 好在我自学能力很强, 基本碰到的问题都能搞得定.

    近期研究github开源项目有几个发现, 代码多带有:

    1. from __future__ import absolute_import
    2. from __future__ import unicode_literals
    3. 在根package的 __init__.py, 加上版本号和作者等信息,
    __version__ = '0.0.2'  
    __author__ = 'somebody'
    4. 如果源码保存为utf-8格式, 文件头加上如下注释,   
    # -*- coding: utf-8 -*- 


    ==============================
    __future__的absolute_import
    ==============================
    from __future__ import absolute_import, 字面理解好像是仅仅允许绝对引用, 其实不然, 真实意思是禁用 implicit relative import, 但并不会禁掉 explicit relative import.

    举个例子, 目录结构如下,

    src
        -my_app
            -__init__.py 
            -cake      
                |- __init__.py      
                |- icing.py      
                |- sponge.py   
            -drink      
                |- __init__.py      
                |- water.py      
     

    要在 sponge.py 引用 icing , 有多种方法:
    1. import icing # implicit relative import, py2已强烈不推荐使用, py3已经不可用了.
    2. from . import icing # explicit relative import, python.org 官方不推荐.
    3. from cake import icing # absolute import, python 官方推荐.

    总结一下, 最好的做法应该是:
    (1) 将 src 目录加到 PYTHONPATH 中
    (2) 在 src 目录下家里一个 root package, 比如名称就叫 my_app
    (3) import 时候都用 my_app.subpackage 或 my_app.module 这样绝对路径的写法,
    比如 import my_app.module 或 from my_app import module




    --------------------------
    使用absolute_import, 常碰到的一个问题
    --------------------------
    使用__future__ absolute_import 之后, 常遇到的如下这一问题, 示例:   
    -PackageA
     |- module1.py  
     |- module2.py  
     |- __init__.py  

    module1.py 的代码示例:

    from __future__ import absolute_impact  
    from . import module2 #引入同包下的另一个module  
    if __name__=="__main__":      
        print("module2 was imported in module1.")  

    运行 module1.py 会报错, 报错信息: ValueError: Attempted relative import in non-package.
    原因分析: from . import module2 这样的写法是显式相对引用, 这种引用方式只能用于 package 中, 而不能用于主模块中. 因为[主module]的name总是为 __main__, 并没有层次结构, 也就无从谈起相对引用了.
    换句话, if __name__=="__main__": 和相对引用是不能并存的.

    解决方法:
    方法1: 在 module1 中使用绝对引用, 这个最简单了, 但相对引用的好处也没了.
    方法2: 使用 python -m 来启动你的 module1.py, 这个也不推荐.
    方法3(推荐): 在 module1 中, 加个main()函数, 然后再新建一个 PackageA/entry.py 做为主程序, 在 entry.py 中使用绝对引用来导入 module1 , 并调用 module1.main(), 这一办法虽不完美, 但我觉得是最好的方法了.


    ==============================
    unicode_literals
    ==============================
    from __future__ import unicode_literals 在python 2.x中, 对于字符串, 默认还不是采用 unicode 编码的, 除非在字符串前加上前缀u. 比如:

    >>>x='中国'  
    >>>x  
    'xd6xd0xb9xfa'  
    >>>print(x)  
    中国  
    >>>
    >>>x=u'中国'  
    >>>x  
    u'u4e2du56fd'  
    >>>print(x)  
    中国  

    在python3中默认的编码采用了unicode, 并取消了前缀u. 如果代码要兼容python2/3, 就很麻烦了.

    通常有如下3种做法, 其中前两个做法都不推荐:
    1. 不管是汉字还是英文, 字符串前面统一不加u. 这种处理方式多数情况下没有问题, 比如print输出, 但字符串如果需要做encode/decode, 就很麻烦.
    2. 加python版本判断, 如果 sys.version >3 的话, 字符串不加前缀u, 如果是py2, 加上前缀u. 可以想象, 业务逻辑中再加上这样的判断, 代码会变得很难看.
    3. 现在有第3种, 即引入unicode_literals, from __future__ import unicode_literals, 这样在py2下, '中国'这样的字符串不用家前缀u, 也是unicode编码.


    ==============================
    引申阅读
    ==============================
    http://blog.ludovf.net/python-str-unicode/
    http://blogs.skicelab.com/maurizio/unicode-common-pitfalls.html

  • 相关阅读:
    矩阵补全(Matrix Completion)和缺失值预处理
    【机器学习基础】对 softmax 和 cross-entropy 求导
    Mendeley使用小技巧
    [Active Learning] Multi-Criteria-based Active Learning
    回归树(Regression Tree)
    Typora + Mathpix Snip,相见恨晚的神器
    【机器学习之数学】02 梯度下降法、最速下降法、牛顿法、共轭方向法、拟牛顿法
    【机器学习之数学】01 导数、偏导数、方向导数、梯度
    “卷积神经网络(Convolutional Neural Network,CNN)”之问
    一篇带你完全掌握线程的博客
  • 原文地址:https://www.cnblogs.com/harrychinese/p/python_future_package.html
Copyright © 2020-2023  润新知