__future__中常用的几个特性

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

近期研究github开源项目几个小心得:

  1. from __future__ import absolute_import
  2. from __future__ import unicode_literals
  3. 根package__init__.py, 加上版本号和作者等信息,
    __version__ = ‘0.0.2‘
    __author__ = ‘somebody‘

__future__的absolute_import

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

举个例子, 目录结构如下,
-cake
|- __init__.py
|- icing.py
|- sponge.py
-drink
|- __init__.py
|- water.py

在 sponge.py 引用 icing , 有多种方法:
* import icing # implicit relative import, py2已强烈不推荐使用, py3已经不可用了
* from . import icing # explicit relative import, python.org 官方虽不推荐, 但这却是事实标准
* from cake import icing # absolute import , python 官方推荐.

使用__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.")

运行会报错, 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  
‘\xd6\xd0\xb9\xfa‘  
>>>print(x)  
中国  
>>>x=u‘中国‘  
u‘\u4e2d\u56fd‘  
>>>print(x)  
中国  

在python3中默认的编码采用了unicode, 并取消了前缀u. 如果代码要兼容python2/3, 就很麻烦了. 下面的两个选择都不方便:
1. 字符串前面不加u. 这种处理方式多数情况下没有问题, 比如print输出, 但因为汉字在py2和py3的编码方式不一样, 如果进行编码转换就麻烦了.
2. 加python版本判断, if 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

__future__中常用的几个特性

上一篇:[Leetcode]-- Combinations


下一篇:vijos1218 数字游戏 (环形dp)