Python 的编码问题

使用 Python 最烦的就是处理编码问题,有几点体会:

0、所有数据一律编码为 UTF-8,这样较为合适

1、 Windows 默认的编码不是 UTF-8,使用 open() 函数读写文件的时候如果不指定编码就容易出问题。 建议使用 open(FILENAME, ‘r’, encoding=’utf-8′) 这种形式

2、Python 2 默认的编码不是 UTF-8,使用前先指定编码:

import sys

reload(sys)

sys.setdefaultencoding(‘utf-8’)

即便如此,如果输入不是 utf-8 编码的数据,在经过字符串相关函数处理后,返回的结果仍可能是 ANSI 格式,特别是和字符串常量混在一起运算的时候。这是 Python 2 最大的问题之一。

 

3、 Python 3 默认的编码是 UTF-8,建议使用 Python 3

4、文本数据在使用 encode 函数编码之后,输出到文件或者数据库时要用 decode 函数解码,否则很可能会发现最后输出的数据是二进制形式的,需要再次读取后用 decode 函数解码。

5、unicode 没有所谓的“标点符号”字符集,只能在沿用 string.punctuation 的基础上自己加入想要的字符。 或者使用正则表达式选择文本中想保留的字符

6、print 函数在控制台输出的编码格式是由控制台的编码决定的。 比如 Windows 中文版使用的是 ANSI 编码,因此如果 print 函数要输出一个 UTF-8 编码的数据,很可能会遇到错误 (比如\xe6 这样的字符),因此输出的时候需要改为形如  print s.encode(‘utf-8′,’ignore’)。(print 函数遇到二进制编码的文本数据时会自动解码)

Install PyLucene 6,7,8 on Windows 10 64bit

update 2021.10: minor fixes. Tested OK with PyLucene 8.9

update 2019.10: add support for PyLucene 8.1.1

update 2019.03: add support for Pylucene 7.7.1+ and clarify some steps

update 2017.07: add support for Python 3

 

Prerequisites

Install Python 2.7.x or Python 3.4+ or Anaconda (Python 2.7.x or Python 3.4+)

Install python packages: numpy, scipy and gensim

Install JDK 1.8 (64 bit) and set environment variables

*The latest JDK 1.8.x is recommended

*JDK 10+ may be incompatible

*Anaconda is recommended since some people seems to have difficulties with raw Python

*If you use raw Python instead of Anaconda, then you may need to add environment variables such as PYTHONHOME and PYTHONPATH to ensure that python can be called on command-line prompt. For Anaconda user, it is recommended to use Anaconda prompt.

  1. JAVA_HOME=C:\jdk1.8.0_06 (or other path)
  2. add %JAVA_HOME%\bin to PATH
  3. CLASSPATH=.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
  4. add CLASSPATH as an environment variable
  5. add %JAVA_HOME%\jre\bin\server to PATH
  6. Install one of the following libraries subject to your environment:
  • Visual C++ library for Python 2.7
    • (www.microsoft.com/en-us/download/details.aspx?id=44266)
  • Visual C++ 2015 Build Tools for Python
    • (http://landinghub.visualstudio.com/visual-cpp-build-tools)
  • Visual Studio 2015+  (community version is enough. Choose c++ related tools and all versions of SDK to install in the VS installer)
    • (https://visualstudio.microsoft.com)

Step 1. Install Apache Ant and set environment variables
1. specify ANT_HOME and add ANT_HOME as an environment variable
2. add %ANT_HOME%\bin to PATH
Step 2. Install cygwin 64 and set environment variables
0. When installing cygwin, choose “Devel” from “Default” to “Installed”
*the space of all packages under “Devel” category are quite large (30~70 GB). “Default” with some basic gcc/g++ tools, libraries and make/cmake utilities are already enough for PyLucene installation.
*choose “Debug” from “INSTALL” to “Unstall” or “Default” can save a lot of space.

1. specify CYGWIN_HOME and add CYGWIN_HOME as an environment variable
2. add %CYGWIN_HOME%\bin to PATH
restart your computer

 

Step 3. Download source code of PyLucene and extract, we obtain a directory named ‘PyLucene-6.5’
* For PyLucene 7 user, the latest Pylucene 7.7.1 is recommended because
the previous PyLucene 7.x may encouter errors during the installation
process.

Step 4. Open Anaconda prompt, execute command under directory JCC
1. python setup.py build
2. python setup.py install
restart your computer
for Linux user, edit line 71 of setup.py to specify your JAVA home (For example, ‘linux’: JAVAHOME) or simply set a JCC_JDK environment variable sharing same value with JAVA_HOME.

Step 5. Edit PyLucene-6.5/Makefile

first comment the default configuration (by adding ‘#’) like the following
# Mac OS X 10.12 (64-bit Python 2.7, Java 1.8)
#PREFIX_PYTHON=/Users/vajda/apache/pylucene/_install
#ANT=/Users/vajda/tmp/apache-ant-1.9.3/bin/ant
#PYTHON=$(PREFIX_PYTHON)/bin/python
#JCC=$(PYTHON) -m jcc.__main__ –shared –arch x86_64
#NUM_FILES=8

And then insert the following configuration (the following are just examples)

PREFIX_PYTHON=D:/Progra~2/Anaconda2
ANT=D:/apache-ant-1.9.7/bin/ant
JAVA_HOME=C:/Progra~1/Java/jdk1.8.0_101
PYTHON=$(PREFIX_PYTHON)/python.exe
JCC=$(PYTHON) -m jcc
NUM_FILES=8

*for PyLucene 8 installation, set NUM_FILES=10. If encounter [WinError 267] when executing ‘make install’, execute ‘make clean’ and then ‘make install’ again.

*if the path contains blank space, you need to replace it by dos path like ‘C:/PROGRA~1’

*if you create a Anaconda environment, then change PREFIX_PYTHON to the root directory of this environment. (e.g Anaconda2/envs/ENVIRONMENT_NAME)

 

Step 6. Execute command ‘make’ under directory ‘PyLucene-6.5.0’ to build the whole project

*use command “make -j2” or “make -j4” to speed up

Step 7. Execute command ‘make install’ under directory ‘PyLucene-6.5.0’

 

Frequently Encountered Problems
1. Python (actually ‘setuptools’ package) cannot call Visual C++ (MSVC) to compile the project
solution: Rewrite PYTHON_PATH\Lib\distutils\distutils.cfg like the following
[build]
compiler=msvc

[build_ext]
compiler=msvc

2. It fails when compiling JCC
solution: open setup.py and
find line ‘win32’: [“/EHsc”, “/D_CRT_SECURE_NO_WARNINGS”],
replace this line by

‘win32’: [“/EHsc”, “/D_CRT_SECURE_NO_WARNINGS”,”/bigobj”],

3. [WinError 267] the directory name is invalid

replace NUM_FILES=8 by NUM_FILES=10 in Makefile.

execute ‘make clean’, and then execute ‘make’ to compile the whole project again

4. JCC_JDK not found (may encounter on Linux)

set “JCC_JDK” as environment variable. The value is  same as JAVA_HOME

5. encounter “dynamic mode does not define module export function” when “import lucene” in Python prompt (may encounter on linux)

remove lucene and jcc packages by execute “pip uninstall lucene” and “pip uninstall jcc”

edit pylucene-6.5/jcc/setup.py. replace the line 71 by ‘linux’:JAVAHOME,

remove jcc/build folder and execute “make clean” under pylucene-6.5 directory.

install jcc and pylucene again

Windows 10 64 bit 编译安装 PyLucene 6, 7, 8

update 2021.09: 更新了对 PyLucene 7 和 8 的支持。

update 2017.07: 添加了对 Python 3 的支持

这可能是互联网上第一篇详细介绍 Windows 下安装新版本 Pylucene 的文章。PyLucene 4 以下原本都有提供 windows 下的安装包,但是新版本没有了。

本文允许带修改的转载,但转载时请注明原文出处: lxsay.com

本文也适用于 32 位的 Windows 系统,只要把安装的软件都改成 32 位的版本就可以了

 

前提条件:

  1. 安装 python ( 本文以 Python 2.7.13 为例,Python 3.4 以上的版本也可以 ) 环境(推荐 Anaconda,自带 gensim, numpy, scipy 等在 Windows 下比较难安装的库).
  2. 安装 JDK 1.8 ( 64 位版本) 并配置环境变量 (推荐按照这篇文章操作:http://www.cnblogs.com/shinge/p/5500002.html),并且配置JRE的环境变量(将 JAVA_HOME/jre/bin/server 这个路径也加进 path 环境变量)
  3.  安装 VC for Python 2.7 ( www.microsoft.com/en-hk/download/details.aspx?id=44266 )。  如果是 Python 3,安装 Visual Studio (安装时选择所有版本的 C/C++开发工具以及其中的VC 14.0和14.1的运行库与工具) 或者 Visual C++ 2015 Build Tools (http://landinghub.visualstudio.com/visual-cpp-build-tools),现在整合以后中文名叫作 “Visual Studio 生成工具”。

 

步骤1.   安装 Apache Ant 并配置环境变量(在 path 环境变量中添加 Ant 安装主目录下的 bin 目录路径,和后面配置的 ant 可执行文件路径不一样)

步骤2.  安装 cygwin 64 bit (用于在 windows 系统中执行 linux 的命令),安装时在选择 packages 的窗口将 “Devel” 项由 “Default” 改为 “Installed”。 并且配置 cygwin 64 的环境变量(在 path 环境变量中添加 cygwin 64 安装主目录下的 bin 目录路径),重启电脑使之生效。Devel的包占用空间比较大,也可以保持 Default,然后只查找并安装 make/cmake/gcc/g++ 相关的包。

步骤2.1  打开 Anaconda Prompt,分别输入 java, javac, ant, make, cmake, gcc, g++ 这几个命令进行测试,如果显示不存在这样的命令或程序,说明环境变量配置有问题,需要重新进行配置。

步骤3.  下载并解压 pylucene 的 源代码 (一般解压出来的文件夹叫作 pylucene-6.4.1 之类)

步骤4.   对于 PyLucene 6.5 以下(不包含 6.5)的版本,进入 pylucene 安装文件夹下的 JCC 文件夹,修改 setup.py文件, 在 CFLAGS 配置这里,在 ‘win32’ 后面添加 “/bigobj” 这个参数,如下面所示

CFLAGS = {
‘darwin’: [‘-fno-strict-aliasing’, ‘-Wno-write-strings’,
‘-mmacosx-version-min=10.5’],
‘ipod’: [‘-Wno-write-strings’],
‘linux2’: [‘-fno-strict-aliasing’, ‘-Wno-write-strings’],
‘sunos5’: [‘-features=iddollar’,
‘-erroff=badargtypel2w,wbadinitl,wvarhidemem’],
‘win32’: [“/EHsc”, “/D_CRT_SECURE_NO_WARNINGS”,”/bigobj”], # MSVC 9 (2008)
‘mingw32’: [‘-fno-strict-aliasing’, ‘-Wno-write-strings’],
‘freebsd7’: [‘-fno-strict-aliasing’, ‘-Wno-write-strings’],
}

如果不添加 “/bigobj” 参数, 在编译 pylucene 时会提示文件过大,编译器无法编译

update: 在 pylucene 6.5 中,这个问题已经被解决,不需要添加此参数

 

步骤5.   在命令行下(推荐用 Anaconda prompt,如果用 windows 命令行的话要确保设置了 python 的环境变量,不然没办法运行)进入 jcc 文件夹,输入 python setup.py build ,如果没有错误信息,继续输入 python setup.py install 安装 JCC 。重启电脑

步骤6.    进入 pylucene-6.2.0 文件夹(根据要安装的版本而定,比如 pylucene-6.4.1 之类),修改 Makefile文件

首先注释掉(通过在每行前面添加’#’符号) 这一段默认配置

# Mac OS X 10.12 (64-bit Python 2.7, Java 1.8)
PREFIX_PYTHON=/Users/vajda/apache/pylucene/_install
ANT=/Users/vajda/tmp/apache-ant-1.9.3/bin/ant
PYTHON=$(PREFIX_PYTHON)/bin/python
JCC=$(PYTHON) -m jcc.__main__ –shared –arch x86_64
NUM_FILES=8

然后插入

PREFIX_PYTHON=D:/Progra~2/Anaconda2
ANT=D:/apache-ant-1.9.7/bin/ant
JAVA_HOME=C:/Progra~1/Java/jdk1.8.0_101
PYTHON=$(PREFIX_PYTHON)/python.exe
JCC=$(PYTHON) -m jcc –shared
NUM_FILES=8

*在 pylucene 6.5 中 JCC 项不再接受 shared 参数,因此应该改为 JCC=$(PYTHON) -m jcc, 否则安装时会出错

                *对于 pylucene 7 和 8,将 NUM_FILES 设置为10

其中 PREFIX_PYTHON 是 python 的安装主目录,如果你创建了一个新的 Anaconda 环境并在该环境下编译,请将 PREFIX_PYTHON 换成该环境的根目录 (一般是 Anaconda2/envs/环境名)

ANT 是 ant 的二进制可执行文件的路径(注意不是安装目录而是可执行文件路径)

NUM_FILES 参数用于指定中间文件的分割数, 使得编译器可以处理大的文件,但是如果修改为其他数值可能会引起错误。 因此最好的办法还是在前一步指定 vc的参数 “/bigobj”

另外需要注意的是,Makefile 不接受带有空格的路径,因此如果路径带有空格的话请用命令行使用的缩写路径(又叫做 dos path, 比如上面这段就采用了这种写法)

步骤7.   运行 make 进行编译(注意:如果之前没有安装并配置 cygwin64 的话,这一步会无法进行下去)。如果是中国国内的网络,建议使用 VPN 或者能够访问外网的翻墙工具,因为这一步会从 maven 仓库上下载需要的 jar 包,可能会出现编译到一半自动中止的情况,此时应该多执行几次 make 命令,让 jar 包全部下载完成。

步骤8.   编译完成后运行 make test 进行测试,由于项目的一些 bug,有几个检测 PyLucene 异常抛出的测试不会通过,但并无大碍。

步骤9.   运行 make install 进行安装

 

常见问题:

1. 编译安装 JCC 时无法使用 MSVC 编译,python 总是自动用 gcc 进行编译:要改成用 visual studio c++ 编译的话,需要编辑 python安装主目录\Lib\distutils下的distutils.cfg文件,将文件内容修改为下面所示

[build]
compiler=msvc

[build_ext]
compiler=msvc

其实本质上就是修改 setuptools 的配置文件

第二种办法是运行 setup.py 文件安装时添加参数变为  python setup.py build –compiler=msvc   但是此方法在接下来编译安装 pylucene 时会失效,因为 make 无法指定 python 使用的 C/C++ 编译器

2. make test 给出 error 123:     linux 下出错的原因在于 Lucene 的测试代码使用了旧版 python 的异常。将 test_Pylucene.py 中的 WindowsError 改为 OSError 就可以。  Windows 下出错的原因也是如此,但是涉及的文件比较多,改起来比较麻烦,所以直接忽略

3.  make 时提示 from jcc import _jcc 找不到 dll:主要原因是 JAVA 的环境变量配置不正确,找不到 jvm.dll。将包含 jvm.dll 的 JRE 目录路径加入 path 环境变量即可(如JRE\bin\server)。如果在编译安装 JCC 这一步之前没有设定好 JDK 的系统变量,也会出现这类错误。 建议设定环境变量后重启电脑一次。如果设定环境变量后仍出现这样的错误,可以修改 JCC 目录下的 setup.py 文件,将 ‘JAVAHOME’ 修改为 JDK 的实际目录路径,然后删掉 build 目录,重新安装 jcc

4. 用 pylucene 6.2 和 6.4 建立的索引可以互相兼容 , 但 pylucene 4 建立的索引不能在 6.2 以上版本使用(需要使用 IndexUpdater 包处理)。程序代码也是,因为很多函数和定义在新版本中被移除了

Java 类名冲突的折衷办法

考虑一个java项目的加载项

import org.carrot2.core.Document;

import org.bson.Document;

显然不能同时加载以上两个包,因为它们的类名都是Document

但假如程序中两个Document类都需要用到的话,可以作如下折衷

加载项:

import org.carrot2.core.Document;

TODO 代码(以 mongoDB-driver 为例):

MongoCollection<org.bson.Document> collection = mongoDatabase.getCollection(DATABASE_NAME);

 

也就是只加载一个包,而另一个包的类在使用时写上全名。

WordPress 提示 “建立数据库连接时出错”

刚刚把 wordpress 安装在 VPS 上的时候,经常遇到“建立数据库连接时出错”这样的错误。

一开始以为是黑客攻击,于是采用了很多安全措施,但收效甚微。

后来觉得是内存使用方面的问题,于是限制 wordpress 的最大使用内存数量,问题仍无改善。

最后发现为 vps 增加一个 swap 分区,并且修改 mysql 的配置文件中的最大连接数项 “max_connections” 为一个较小的数之后,问题解决。

Windows环境下设定GCC的栈空间大小

过去一年在研究二维条带装箱问题的精确搜索算法。写了一个迭代加深搜索,发现自己的程序运行大规模数据的时候总会出现一些莫名其妙的错误,分析之后发现是栈空间不够。按道理说该问题的深度优先搜索算法的空间复杂度应该是O(n·f(n)),其中n是问题规模,表示当前找到一条从根节点到解的长度为n的路径,f(n)是一个关于n的多项式函数,表示每个节点使用的数组的大小,应该不容易溢出才对。

之前网上的文章多数是传授如何在VC下更改栈空间,而我使用的编译器是GCC,相关文章很少。搜索一番以后得出如下结果

以下摘自 https://gcc.gnu.org/onlinedocs/gcc-4.0.1/gnat_ugn_unw/Setting-Stack-Size-from-gnatlink.html

“Under Windows systems, it is possible to specify the program stack size from gnatlink using either:

  • using -Xlinker linker option
              $ gnatlink hello -Xlinker --stack=0x10000,0x1000
    

    This sets the stack reserve size to 0x10000 bytes and the stack commit size to 0x1000 bytes.

  • using -Wl linker option
              $ gnatlink hello -Wl,--stack=0x1000000
    

    This sets the stack reserve size to 0x1000000 bytes. Note that with -Wl option it is not possible to set the stack commit size because the coma is a separator for this option.”

  • 总结一下,就是在调用连接器(linker)的时候加上运行参数
    -Wl,--stack=SIZE_STACK

    其中SIZE_STACK是待设定的栈空间大小,如果用DEV-C++的话可以在“编译器设置”栏中设定。需要注意的一点是,设置比较大的栈空间的时候需要使用64位位宽(mx)编译程序,在DEV-C++的编译器设置栏目中仍然可以找到。