把项目从Python2.x移植到Python3.x的经验总结

经历移植jinja2到python3的痛苦之后,我把项目暂时放一放,因为我怕打破python3的兼容。我的做法是只用一个python2的代码库,然后在安装的时候用2to3工具翻译成python3。不幸的是哪怕一点点的改动都会打破迭代开发。如果你选对了python的版本,你可以专心做事,幸运的避免了这个问题。

来自MoinMoin项目的Thomas Waldmann通过我的python-modernize跑jinja2,并且统一了代码库,能同时跑python2,6,2,7和3.3。只需小小清理,我们的代码就很清晰,还能跑在所有的python版本上,并且看起来和普通的python代码并无区别。

受到他的启发,我一遍又一遍的阅读代码,并开始合并其他代码来享受统一的代码库带给我的快感。

下面我分享一些小窍门,可以达到和我类似的体验。

放弃python 2.5 3.1和3.2

这是最重要的一点,放弃2.5比较容易,因为现在基本没人用了,放弃3.1和3.2也没太大问题,应为目前python3用的人实在是少得可怜。但是你为什么放弃这几个版本呢?答案就是2.6和3.3有很多交叉哦语法和特性,代码可以兼容这两个版本。

  • 字符串兼容。2.6和3.3支持相同的字符串语法。你可以用 "foo" 表示原生字符串(2.x表示byte,3.x表示unicode),u"foo" 表示unicode字符串,b"foo" 表示原生字符串或字节数组。
  • print函数兼容,如果你的print语句比较少,那你可以加上"from __future__ import print_function",然后开始使用print函数,而不是把它绑定到别的变量上,进而避免诡异的麻烦。
  • 兼容的异常语法。Python 2.6引入的 "except Exception as e" 语法也是3.x的异常捕捉语法。
  • 类修饰器都有效。这个可以用在修改接口而不在类结构定义中留下痕迹。例如可以修改迭代方法名字,也就是把 next 改成 __next__ 或者把 __str__ 改成 __unicode__ 来兼容python 2.x。
  • 内置next调用__next__或next。这点很有用,因为他们和直接调用方法的速度差不多,所以你不用考虑得太多而去加入运行时检查和包装一个函数。
  • Python 2.6 加入了和python 3.3接口一样的bytearray类型。这点也很有用,因为2.6没有 3.3的byteobject类型,虽然有一个内建的名字但那仅仅只是str的别名,并且使用习惯也有很大差异。
  • Python 3.3又加入了byte到byte和string到string的编码与解码,这已经在3.1和3.2中去掉了,很不幸,他们的接口很复杂了,别名也没了,但至少更比以前的2.x版本更接近了。

最后一点在流编码和解码的时候很有用,这功能在3.0的时候去掉了,直到3.3才恢复。

没错,six模块可以让你走得远一点,但是不要低估了代码工整度的意义。在Python3移植过程中,我几乎对jinja2失去了兴趣,因为代码开始虐我。就算能统一代码库,但还是看起来很不舒服,影响视觉(six.b('foo')和six.u('foo')到处飞)还会因为用2to3迭代开发带来不必要的麻烦。不用去处理这些麻烦,回到编码的快乐享受中吧。jinja2现在的代码非常清晰,你也不用当心python2和3的兼容问题,不过还是有一些地方使用了这样的语句:if PY2:。

接下来假设这些就是你想支持的python版本,试图支持python2.5,这是一个痛苦的事情,我强烈建议你放弃吧。支持3.2还有一点点可能,如果你能在把函数调用时把字符串都包装起来,考虑到审美和性能,我不推荐这么做。

跳过six

six是个好东西,jinja2开始也在用,不过最后却不给力了,因为移植到python3的确需要它,但还是有一些特性丢失了。你的确需要six,如果你想同时支持python2.5,但从2.6开始就没必要使用six了,jinja2搞了一个包含助手的兼容模块。包括很少的非python3 代码,整个兼容模块不足80行。

因为其他库或者项目依赖库的原因,用户希望你能支持不同版本,这是six的确能为你省去很多麻烦。

开始使用Modernize

使用python-modernize移植python是个很好的还头,他像2to3一样运行的时候生成代码。当然,他还有很多bug,默认选项也不是很合理,可以避免一些烦人的事情,然你走的更远。但是你也需要检查一下结果,去掉一些import 语句和不和谐的东西。
修复测试

做其他事之前先跑一下测试,保证测试还能通过。python3.0和3.1的标准库就有很多问题是诡异的测试习惯改变引起的。

写一个兼容的模块

因此你将打算跳过six,你能够完全抛离帮助文档么?答案当然是否定的。你依然需要一个小的兼容模块,但是它足够小,使得你能够将它仅仅放在你的包中,下面是一个基本的例子,关于一个兼容模块看起来是个什么样子:

import sys
PY2 = sys.version_info[0] == 2
if not PY2:
 text_type = str
 string_types = (str,)
 unichr = chr
else:
 text_type = unicode
 string_types = (str, unicode)
 unichr = unichr

那个模块确切的内容依赖于,对于你有多少实际的改变。在Jinja2中,我在这里放了一堆的函数。它包括ifilter, imap以及类似itertools的函数,这些函数都内置在3.x中。(我纠缠Python 2.x函数,是为了让读者能够对代码更清楚,迭代器行为是内置的而不是缺陷) 。

为2.x版本做测试而不是3.x

总体上来说你现在正在使用的python是2.x版本的还是3.x版本的是需要检查的。在这种情况下我推荐你检查当前版本是否是python2而把python3放到另外一个判断的分支里。这样等python4面世的时候你收到的“惊喜”对你的影响会小一点

好的处理:

if PY2:
 def __str__(self):
  return self.__unicode__().encode('utf-8')

相比之下差强人意的处理:

if not PY3:
 def __str__(self):
  return self.__unicode__().encode('utf-8')

字符串处理
Python 3的最大变化毫无疑问是对Unicode接口的更改。不幸的是,这些更改在某些地方非常的痛苦,而且在整个标准库中还得到了不一致地处理。大多数与字符串处理相关的时间函数的移植将完全被废止。字符串处理这个主题本身就可以写成完整的文档,不过这儿有移植Jinja2和Werkzeug所遵循的简洁小抄:

'foo'这种形式的字符串总指的是本机字符串。这种字符串可以用在标识符里、源代码里、文件名里和其他底层的函数里。另外,在2.x里,只要限制这种字符串仅仅可使用ASCII字符,那么就允许作为Unicode字符串常量。
    这个属性对统一编码基础是非常有用的,因为Python 3的正常方向时把Unicode引进到以前不支持Unicode的某些接口,不过反过来却从不是这样的。由于这种字符串常量“升级”为Unicode,而2.x仍然在某种程度上支持Unicode,因此这种字符串常量怎么用都行。
    例如 datetime.strftime函数在Python2里严格不支持Unicode,并且只在3.x里支持Unicode。不过因为大多数情况下2.x上的返回值只是ASCII编码,所以像这样的函数在2.x和3.x上都确实运行良好。

 >>> u'<p>Current time: %s' % datetime.datetime.utcnow().strftime('%H:%M')
 u'<p>Current time: 23:52'

传递给strftime的字符串是本机字符串(在2.x里是字节,而在3.0里是Unicode)。返回值也是本机字符串并且仅仅是ASCII编码字符。 因此在2.x和3.x上一旦对字符串进行格式化,那么结果就一定是Unicode字符串。
    u'foo'这种形式的字符串总指的是Unicode字符串,2.x的许多库都已经有非常好的支持Unicode,因此这样的字符串常量对许多人来说都不应该感到奇怪。

b'foo'这种形式的字符串总指的是只以字节形式存储的字符串。由于2.6确实没有类似Python 3.3所具有的字节对象,而且Python 3.3缺乏一个真正的字节字符串,因此这种常量的可用性确实受到小小的限制。当与在2.x和3.x上具有同样接口的字节数组对象绑定在一起时候,它立刻变得更可用了。
    由于这种字符串是可以更改的,因此对原始字节的更改是非常有效的,然后你再次通过使用inbytes()封装最终结果,从而转换结果为更易读的字符串。

除了这些基本的规则,我还对上面我的兼容模块添加了 text_type,unichr 和 string_types 等变量。通过这些有了大的变化:

  • isinstance(x, basestring) 变成 isinstance(x, string_types).
  • isinstance(x, unicode) 变成 isinstance(x, text_type).
  • isinstance(x, str) 为表明捕捉字节的意图,现在变成 isinstance(x, bytes) 或者 isinstance(x, (bytes, bytearray)).

我还创建了一个 implements_to_string 装饰类,来帮助实现带有 __unicode__ 或 __str__ 的方法的类:

if PY2:
 def implements_to_string(cls):
  cls.__unicode__ = cls.__str__
  cls.__str__ = lambda x: x.__unicode__().encode('utf-8')
  return cls
else:
 implements_to_string = lambda x: x

这个想法是,你只要按2.x和3.x的方式实现 __str__,让它返回Unicode字符串(是的,在2.x里看起来有点奇怪),装饰类在2.x里会自动把它重命名为 __unicode__,然后添加新的 __str__ 来调用 __unicode__ 并把其返回值用 UTF-8 编码再返回。在过去,这种模式在2.x的模块中已经相当普遍。例如 Jinja2 和 Django 中都这样用。

下面是一个这种用法的实例:

@implements_to_string
class User(object):
 def __init__(self, username):
  self.username = username
 def __str__(self):
  return self.username

元类语法的更改
由于Python 3更改了定义元类的语法,并且以一种不兼容的方式调用元类,所以这使移植比未更改时稍稍难了些。Six有一个with_metaclass函数可以解决这个问题,不过它在继承树中产生了一个虚拟类。对Jinjia2移植来说,这个解决方案令我非常 的不舒服,我稍稍地对它进行了修改。这样对外的API是相同的,只是这种方法使用临时类与元类相连接。 好处是你使用它时不必担心性能会受影响并且让你的继承树保持得很完美。
这样的代码理解起来有一点难。 基本的理念是利用这种想法:元类可以自定义类的创建并且可由其父类选择。这个特殊的解决方法是用元类在创建子类的过程中从继承树中删除自己的父类。最终的结果是这个函数创建了带有虚拟元类的虚拟类。一旦完成创建虚拟子类,就可以使用虚拟元类了,并且这个虚拟元类必须有从原始父类和真正存在的元类创建新类的构造方法。这样的话,既是虚拟类又是虚拟元类的类从不会出现。
这种解决方法看起来如下:

def with_metaclass(meta, *bases):
 class metaclass(meta):
  __call__ = type.__call__
  __init__ = type.__init__
  def __new__(cls, name, this_bases, d):
   if this_bases is None:
    return type.__new__(cls, name, (), d)
   return meta(name, bases, d)
 return metaclass('temporary_class', None, {})
下面是你如何使用它:

class BaseForm(object):
 pass

class FormType(type):
 pass

class Form(with_metaclass(FormType, BaseForm)):
 pass

字典
Python 3里更令人懊恼的更改之一就是对字典迭代协议的更改。Python2里所有的字典都具有返回列表的keys()、values()和items(),以及返回迭代器的iterkeys(),itervalues()和iteritems()。在Python3里,上面的任何一个方法都不存在了。相反,这些方法都用返回视图对象的新方法取代了。

keys()返回键视图,它的行为类似于某种只读集合,values()返回只读容器并且可迭代(不是一个迭代器!),而items()返回某种只读的类集合对象。然而不像普通的集合,它还可以指向易更改的对象,这种情况下,某些方法在运行时就会遇到失败。

站在积极的一方面来看,由于许多人没有理解视图不是迭代器,所以在许多情况下,你只要忽略这些就可以了。
Werkzeug和Dijango实现了大量自定义的字典对象,并且在这两种情况下,做出的决定仅仅是忽略视图对象的存在,然后让keys()及其友元返回迭代器。

由于Python解释器的限制,这就是目前可做的唯一合理的事情了。不过存在几个问题:

  • 视图本身不是迭代器这个事实意味着通常状况下你没有充足的理由创建临时对象。
  • 内置字典视图的类集合行为在纯Python里由于解释器的限制不可能得到复制。
  • 3.x视图的实现和2.x迭代器的实现意味着有大量重复的代码。

下面是Jinja2编码库常具有的对字典进行迭代的情形:

if PY2:
 iterkeys = lambda d: d.iterkeys()
 itervalues = lambda d: d.itervalues()
 iteritems = lambda d: d.iteritems()
else:
 iterkeys = lambda d: iter(d.keys())
 itervalues = lambda d: iter(d.values())
 iteritems = lambda d: iter(d.items())

为了实现类似对象的字典,类修饰符再次成为可行的方法:

if PY2:
 def implements_dict_iteration(cls):
  cls.iterkeys = cls.keys
  cls.itervalues = cls.values
  cls.iteritems = cls.items
  cls.keys = lambda x: list(x.iterkeys())
  cls.values = lambda x: list(x.itervalues())
  cls.items = lambda x: list(x.iteritems())
  return cls
else:
 implements_dict_iteration = lambda x: x

在这种情况下,你需要做的一切就是把keys()和友元方法实现为迭代器,然后剩余的会自动进行:

@implements_dict_iteration
class MyDict(object):
 ...

 def keys(self):
  for key, value in iteritems(self):
   yield key

 def values(self):
  for key, value in iteritems(self):
   yield value

 def items(self):
  ...

通用迭代器的更改
由于一般性地更改了迭代器,所以需要一丁点的帮助就可以使这种更改毫无痛苦可言。真正唯一的更改是从next()到__next__的转换。幸运的是这个更改已经经过透明化处理。 你唯一真正需要更改的事情是从x.next()到next(x)的更改,而且剩余的事情由语言来完成。

如果你计划定义迭代器,那么类修饰符再次成为可行的方法了:

if PY2:
 def implements_iterator(cls):
  cls.next = cls.__next__
  del cls.__next__
  return cls
else:
 implements_iterator = lambda x: x
为了实现这样的类,只要在所有的版本里定义迭代步长方法__next__就可以了:

@implements_iterator
class UppercasingIterator(object):
 def __init__(self, iterable):
  self._iter = iter(iterable)
 def __iter__(self):
  return self
 def __next__(self):
  return next(self._iter).upper()

转换编解码器
Python 2编码协议的优良特性之一就是它不依赖于类型。 如果你愿意把csv文件转换为numpy数组的话,那么你可以注册一个这样的编码器。然而自从编码器的主要公共接口与字符串对象紧密关联后,这个特性不再为众人所知。由于在3.x里转换的编解码器变得更为严格,所以许多这样的功能都被删除了,不过后来由于证明转换编解码有用,在3.3里重新引入了。基本上来说,所有Unicode到字节的转换或者相反的转换的编解码器在3.3之前都不可用。hex和base64编码就位列与这些编解码的之中。

下面是使用这些编码器的两个例子:一个是字符串上的操作,一个是基于流的操作。前者就是2.x里众所周知的str.encode(),不过,如果你想同时支持2.x和3.x,那么由于更改了字符串API,现在看起来就有些不同了:

>>> import codecs
>>> codecs.encode(b'Hey!', 'base64_codec')
'SGV5IQ==\n'

同样,你将注意到在3.3里,编码器不理解别名,要求你书写编码别名为"base64_codec"而不是"base64"。

(我们优先选择这些编解码器而不是选择binascii模块里的函数,因为通过对这些编码器增加编码和解码,就可以支持所增加的编码基于流的操作。)

其他注意事项
仍然有几个地方我尚未有良好的解决方案,或者说处理这些地方常常令人懊恼,不过这样的地方会越来越少。不幸是的这些地方的某些现在已经是Python 3 API的一部分,并且很难被发现,直到你触发一个边缘情形的时候才能发现它。

在Linux上处理文件系统和文件IO访问仍然令人懊恼,因为它不是基于Unicode的。Open()函数和文件系统的层都有危险的平台指定的缺省选项。例如,如果我从一台de_AT的机器SSH到一台en_US机器,那么Python对文件系统和文件操作就喜欢回退到ASCII编码上。

我注意到通常Python3上对文本操作最可靠的同时也在2.x正常工作的方法是仅仅以二进制模式打开文件,然后显式地进行解码。另外,你也可以使用2.x上的codec.open或者io.open函数,以及Python 3上内置的带有编码参数的Open函数。

标准库里的URL不能用Unicode正确地表示,这使得一些URL在3.x里不能被正确的处理。

由于更改了语法,所以追溯对象产生的异常需要辅助函数。通常来说这非常罕见,而且很容易处理。下面是由于更改了语法所遇到的情形之一,在这种情况下,你将不得不把代码移到exec块里。

 if PY2:
  exec('def reraise(tp, value, tb):\n raise tp, value, tb')
 else:
  def reraise(tp, value, tb):
   raise value.with_traceback(tb)

如果你有部分代码依赖于不同的语法的话,那么通常来说前面的exec技巧是非常有用的。不过现在由于exec本身就有不同的语法,所以你不能用它来执行任何命名空间上的操作。下面给出的代码段不会有大问题,因为把compile用做嵌入函数的eval可运行在两个版本上。另外你可以通过exec本身启动一个exec函数。

exec_ = lambda s, *a: eval(compile(s, '<string>', 'exec'), *a)

如果你在Python C API上书写了C模块,那么自杀吧。从我知道那刻起到仙子仍然没有工具可处理这个问题,而且许多东西都已经更改了。借此机会放弃你构造模块所使用的这种方法,然后在cffi或者ctypes上重新书写模块。如果这种方法还不行的话,因为你有点顽固,那么只有接受这样的痛苦。也许试着在C预处理器上书写某些令人讨厌的事可以使移植更容易些。

使用Tox来进行本地测试。能够立刻在所有Python版本上运行你的测试是非常有益的,这将为你找到许多问题。

展望

统一2.x和3.x的基本编码库现在确实可以开始了。移植的大量时间仍然将花费在试图解决有关Unicode以及与其他可能已经更改了自身API的模块交互时API是如何操作上。无论如何,如果你打算考虑移植库的话,那么请不要触碰2.5以下的版本、3.0-3.2版本,这样的话将不会对版本造成太大的伤害。

(0)

相关推荐

  • 对Python的Django框架中的项目进行单元测试的方法

     Python中的单元测试 我们先来回顾一下Python中的单元测试方法. 下面是一个 Python的单元测试简单的例子: 假如我们开发一个除法的功能,有的同学可能觉得很简单,代码是这样的: def division_funtion(x, y): return x / y 但是这样写究竟对还是不对呢,有些同学可以在代码下面这样测试: def division_funtion(x, y): return x / y if __name__ == '__main__': print division

  • Python之Web框架Django项目搭建全过程

    Python之Web框架Django项目搭建全过程 IDE说明: Win7系统 Python:3.5 Django:1.10 Pymysql:0.7.10 Mysql:5.5 注:可通过pip freeze查看已安装库版本信息. Django 是由 Python 开发的一个免费的开源网站框架,可以用于快速搭建高性能,优雅的网站! Django 特点 强大的数据库功能 用python的类继承,几行代码就可以拥有一个丰富,动态的数据库操作接口(API),如果需要你也能执行SQL语句. 自带的强大的后

  • 详解使用Nginx和uWSGI配置Python的web项目的方法

    基于python的web项目,常见的部署方法有: fcgi:用spawn-fcgi或者框架自带的工具对各个project分别生成监听进程,然后和http服务互动. wsgi:利用http服务的mod_wsgi模块来跑各个project. 不过还有个uwsgi,它既不用wsgi协议也不用fcgi协议,而是自创了一个uwsgi的协议,据作者说该协议大约是fcgi协议的10倍那么快.uWSGI的主要特点如下: 超快的性能. 低内存占用(实测为apache2的mod_wsgi的一半左右). 多app管理

  • python好玩的项目—色情图片识别代码分享

    一.实验简介 本实验将使用 Python3 去识别图片是否为色情图片,我们会使用到 PIL 这个图像处理库,会编写算法来划分图像的皮肤区域 1.1. 知识点 Python 3 的模块的安装 Python 3 基础知识 肤色像素检测与皮肤区域划分算法 Pillow模块的使用 argparse 模块的使用 1.2. 效果展示 二.实验步骤 2.1. 安装包 PIL 2009年之后就没有更新了,也不支持 Python3 ,于是有了 Alex Clark 领导的公益项目 Pillow,Pillow 是一

  • Python自动化运维和部署项目工具Fabric使用实例

    Fabric 是使用 Python 开发的一个自动化运维和部署项目的一个好工具,可以通过 SSH 的方式与远程服务器进行自动化交互,例如将本地文件传到服务器,在服务器上执行shell 命令. 下面给出一个自动化部署 Django 项目的例子 # -*- coding: utf-8 -*- # 文件名要保存为 fabfile.py from __future__ import unicode_literals from fabric.api import * # 登录用户和主机名: env.use

  • 全面了解Python环境配置及项目建立

    一.安装Python Python比较稳定的两个版本是Python 3.5和Python 2.7,我用的是Python 2.7,下载地址是:https://www.python.org/downloads/,下载之后按照正常的软件安装过程安装即可. 配置Python环境变量:控制面板->系统->高级系统设置->环境变量->Path,在Path中添加python的安装路径,例如:C:\Python27:然后,一直点击 确定 or OK.python环境变量即配置完成,打开cmd,输入

  • Python网络爬虫项目:内容提取器的定义

    1. 项目背景 在python 即时网络爬虫项目启动说明中我们讨论一个数字:程序员浪费在调测内容提取规则上的时间,从而我们发起了这个项目,把程序员从繁琐的调测规则中解放出来,投入到更高端的数据处理工作中. 2. 解决方案 为了解决这个问题,我们把影响通用性和工作效率的提取器隔离出来,描述了如下的数据处理流程图: 图中"可插拔提取器"必须很强的模块化,那么关键的接口有: 标准化的输入:以标准的HTML DOM对象为输入 标准化的内容提取:使用标准的xslt模板提取网页内容 标准化的输出:

  • Linux下将Python的Django项目部署到Apache服务器

    这几天花了点时间,将把django开发好的web项目部署到Apache上,参考了官方的一些文档和互联网上的文档,还是花了比较多的时间,这里把配置的过程说一下. 方便有需要的朋友,可以参考,少走弯路! 1. django项目部署环境说明 操作系统 : Red Hat Enterprise Linux Server release 5.3 (Tikanga) x86_64 apache版本 : httpd-2.2.3-22.el5 mod_wsgi版本 : mod_wsgi-3.2-1.el5 fe

  • 把项目从Python2.x移植到Python3.x的经验总结

    经历移植jinja2到python3的痛苦之后,我把项目暂时放一放,因为我怕打破python3的兼容.我的做法是只用一个python2的代码库,然后在安装的时候用2to3工具翻译成python3.不幸的是哪怕一点点的改动都会打破迭代开发.如果你选对了python的版本,你可以专心做事,幸运的避免了这个问题. 来自MoinMoin项目的Thomas Waldmann通过我的python-modernize跑jinja2,并且统一了代码库,能同时跑python2,6,2,7和3.3.只需小小清理,我

  • Python3自带工具2to3.py 转换 Python2.x 代码到Python3的操作

    几乎所有的Python 2程序都需要一些修改才能正常地运行在Python 3的环境下.为了简化这个转换过程,Python 3自带了一个叫做2to3的实用脚本(Utility Script),这个脚本会将你的Python 2程序源文件作为输入,然后自动将其转换到Python 3的形式. 本文介绍一下在windows 10 环境下如何使用这个工具: 1)首先要先安装好python3,可到官网下载https://www.python.org/ 2)使用Windows 命令提示符(cmd)打开2to3.

  • mac下如何将python2.7改为python3

    1.查看当前电脑python版本 python -V  // 显示2.7.x 2.用brew升级python brew update python  3.如果安装成功,去系统目录下回看到两个版本的python cd usr/local/Cellar/ //到此目录下 cd python/ //进入python目录下 查看已安装的python版本,如果有2.x 和 3.x说明安装成功 4.将系统python版本,默认指向python3  (主要修改 ~/.bash_profile文件 和 ~/.b

  • window7下的python2.7版本和python3.5版本的opencv-python安装过程

    花费了整整2天的时间终于学会安装了opencv,换系统的心都有了,由于ubuntu实在不会玩,看来还是老老实实在windows下安装吧,以此作为记录方便以后安装 python2.7版本的opencv安装 1.首先到官网下载64位(以后安装的都是对应64位的程序)python2.7版本并安装,我选择的是安装在D盘命名为python2.7.12文件夹下,将D:\python2.7.12和D:\python2.7.12\Scripts路径加入到环境变量中,注意中间用分号隔开 2.下载opencv.ex

  • vue项目环境搭建 启动 移植操作示例及目录结构分析

    目录 项目搭建 项目创建 项目启动停止 项目目录结构分析 全局脚本配置 index.html详细介绍 main.js入口文件详细 App.vue跟组件介绍 router-index.js 路由介绍 项目搭建 下载node 官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/ 安装cnpm,用淘宝源: npm install -g cnpm --registry=https://registry.npm.taobao.org 检测是否安装成功:cnpm -version

  • Linux环境下python2.7.6升级python3.5.2

    需求 Linux环境下有些是自带的Python2版本有时是刚安装号的Python其他版本,当新版本出来的时候,在开发的时候往往会选择新版本的软件进行安装. 原因 在开发的时候选用新版本的软件进行安装的时候,出于以下角度来考虑的. 老版本的一些第三方软件库会随着新版本软件的更新,老本版所支持的第三方库就没有人去维护和更新了,后面在使用的过程中,如果出现了bug,就会花很大的精力去解决. 步骤 基于上面的要求,我将生产虚机上的ython2.7.6升级python3.5.2,主要步骤如下所示: 去py

  • 在Python 2.7即将停止支持时,我们为你带来了一份python 3.x迁移指南

    目前,Python 科学栈中的所有主要项目都同时支持 Python 3.x 和 Python 2.7,不过,这种情况很快即将结束.去年 11 月,Numpy 团队的一份声明引发了数据科学社区的关注: 这一科学计算库即将放弃对于 Python 2.7 的支持 ,全面转向 Python 3.Numpy 并不是唯一宣称即将放弃 Python 旧版本支持的工具,pandas 与 Jupyter notebook 等很多产品也在即将放弃支持的名单之中.对于数据科学开发者而言,如何将已有项目从 Python

  • 简单了解Python3里的一些新特性

    概述 到2020年,Python2的官方维护期就要结束了,越来越多的Python项目从Python2切换到了Python3.其实在实际工作中,很多伙伴都还是在用Python2的思维写Python3的代码.给大家总结一下Python3一些新的更方便的特性!希望你们看完后也能高效率的编写代码 f-strings (3.6+) 在Python里面,我们经常使用format函数来格式化字符串,例如: user = "Jane Doe"action = "buy"log_me

  • Python使用pyh生成HTML文档的方法示例

    最近在项目中需要将结果导出到HTML中,在网上搜索的时候发现了这个库,通过官方的一些文档以及网上的博客发现它的使用还是很简单的,因此选择在项目中使用它. 在使用的时候发现在Python3中有些问题,网上很多地方都没有提到,因此我在这将它的使用以及我遇到的问题和解决方案整理出来供大家参考 本文主要参考 pyh中文文档 下载的样本也是该文中提到的地址 常规使用 在使用时一般先导入模块: from phy import * 然后可以创建一个PyH对象就像这样 page = PyH(title) 其中t

  • Python常用库大全及简要说明

    环境管理 管理 Python 版本和环境的工具 p:非常简单的交互式 python 版本管理工具.官网 pyenv:简单的 Python 版本管理工具.官网 Vex:可以在虚拟环境中执行命令.官网 virtualenv:创建独立 Python 环境的工具.官网 virtualenvwrapper:virtualenv 的一组扩展.官网 buildout:在隔离环境初始化后使用声明性配置管理.官网 包管理 管理包和依赖的工具. pip:Python 包和依赖关系管理工具.官网 pip-tools:

随机推荐