PyLucene中使用自己的Analyzer

PyLucene通过继承扩展定制

  • 系统:Ubuntu 16.04 64 bit
  • PyLucene:6.4.1
  • JDK8u_121

网上关于如何在 PyLucene 中 Writing Java class extensions in Python 真的太少了,当然如果直接使用 Lucene 就比较简单了,直接继承原来的类就行,但如果既想用 Python,又想用 Lucene,那就只能使用 PyLucene,然后用 Python 来扩展 Java 中的类。

PyLucene基本工作原理

首先必须了解 PyLucene是如何实现的,其实 PyLucene 是在 Python 程序中嵌入了一个 JVM 来使用 Lucene,这个工作主要通过 JCC 来完成,JCC 编译 Lucene 源码为 C++,然后在 Python 中通过 JNI 进行调用。
现在我们希望在 Python 中扩展 Java 源码中的类,仍然要借助 JCC。

添加 Java 源码

假设我们要扩展 Lucene 中的类 A,首先要用 Java 写一个子类 PythonA 继承自 A,通常放在 org.apache.pylucene 里。示例代码如下:

package org.apache.pylucene.analysis;

import java.io.Reader;
import org.apache.lucene.analysis.Analyzer;

public class PythonAnalyzer extends Analyzer {

    private long pythonObject;

    public PythonAnalyzer()
    {
    }

    public void pythonExtension(long pythonObject)
    {
        this.pythonObject = pythonObject;
    }
    public long pythonExtension()
    {
        return this.pythonObject;
    }

    public void finalize()
        throws Throwable
    {
        pythonDecRef();
    }

    public native void pythonDecRef();

/*————————————————————分割线———————————————————————————*/

    @Override
    public native TokenStreamComponents createComponents(final String fieldName);

    @Override
    public native Reader initReader(String fieldName, Reader reader);
}

分割线以上除了构造函数以外不管扩展哪个类都必须这样写,分割线以下根据自己的需求来就好。方法最好用 public 来修饰,用 protected 可能会出错。
写好以后放到可以被 make 到的地方,当然最好放在 org.apache.pylucene 中,然后重新 make、make install。

在 Python 中扩展及遇到的问题

完成上面步骤后,在 Python 中直接继承 PythonA 就行,注意如果有 __init__() 的话,必须调用父类的构造方法。

遇到的问题:

1、Java 中 .class 的用法显然在 Python 中无法使用,而 getClass() 方法是通过对象来调用而不是类,可以考虑 Class.forName(),但是 Lucene 源码中的类使用 Class.forName() 可能找不到,最好使用 findClass() 方法。

>>> import lucene
>>> from lucene import findClass
>>> lucene.initVM(vmargs=['-Djava.awt.headless=true'])
>>> findClass('org/apache/lucene/document/Document')
    <Class: class org.apache.lucene.document.Document>
>>> Class.forName('org.apache.lucene.document.Document')
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    lucene.JavaError: java.lang.ClassNotFoundException: org/apache/lucene/document/Document
>>> Class.forName('java.lang.Object')
    <Class: class java.lang.Object>

2、Java源码中的父类 A 的变量在 Python 的子类中无法访问,可以在PythonA 的代码中添加 相应的 get 方法,提供访问接口。

3、关于处理 Java 中的数组,在 Python 中可以通过如下方式构造 Java 中的数组:

>>> array = JArray('int')(size)
    # the resulting Java int array is initialized with zeroes
>>> array = JArray('int')(sequence)
    # the sequence must only contain ints
    # the resulting Java int array contains the ints in the sequence

要把一个 Java 中的 char 数组转换为 Python 中的 str,只需要执行

''.join(array)

在 Python 中访问的话支持使用 [] 进行访问,可以修改元素内容,但无法改变数组大小。

4、Unicode 对象 s 转为 utf-8 :

s.encode('utf-8')

今天就先写到这里,具体如何自定义 Analyzer 下次再写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值