duktape javascript解释器的python集成
pyduktape2的Python项目详细描述
简介
pyduktape是一个围绕Duktape的python包装器, 一个可嵌入的javascript解释器。
在解释器包装器之上,pyduktape提供了简单的集成 在python和javascript环境之间。你可以通过 python对象到javascript,对其调用方法并访问 属性。类似地,您可以将javascript对象传递给python。
对象从未被复制或序列化。相反,他们通过了 在使用代理对象的两个环境之间。代理对象 将执行委托给原始对象环境。
螺纹
可以从多个线程调用javascript代码。每个 线程将需要使用自己的嵌入式解释器。javascript 返回到python环境的对象只能在 创建它们的同一线程。运行库总是检查这个 条件,如果是 违反了。
开始
安装
从pypi安装:
$ pip install pyduktape2
从github安装最新版本:
$ pip install git+https://github.com/phith0n/pyduktape2
运行javascript代码
要运行javascript代码,需要创建一个执行上下文并 使用方法eval_js:
import pyduktape2 context = pyduktape2.DuktapeContext() context.eval_js("print('Hello, world!');")
每个执行上下文都启动自己的解释器。每个上下文都是 独立的,并绑定到创建它的python线程。记忆是 自动管理。
要评估外部javascript文件,请使用eval_js_file:
// helloWorld.js print('Hello, World!'); # in the Python interpreter import pyduktape2 context = pyduktape2.DuktapeContext() context.eval_js_file('helloWorld.js')
pyduktape支持javascript模块:
// js/helloWorld.js exports.sayHello = function () { print('Hello, World!'); }; // js/main.js var helloWorld = require('js/helloWorld'); helloWorld.sayHello(); # in the Python interpreter import pyduktape2 context = pyduktape2.DuktapeContext() context.eval_js_file('js/main')
如果缺少.js扩展名,则会自动添加。相对的 路径是相对于当前工作目录的,但是您可以 使用set_base_path:
更改基路径# js/helloWorld.js print('Hello, World!'); # in the Python interpreter import pyduktape2 context = pyduktape2.DuktapeContext() context.set_base_path('js') context.eval_js_file('helloWorld')
python和javascript集成
您可以使用set_globals设置javascript全局变量:
import pyduktape2 def say_hello(to): print 'Hello, {}!'.format(to) context = pyduktape2.DuktapeContext() context.set_globals(sayHello=say_hello, world='World') context.eval_js("sayHello(world);")
您可以使用get_global访问javascript全局变量:
import pyduktape2 context = pyduktape2.DuktapeContext() context.eval_js("var helloWorld = 'Hello, World!';") print context.get_global('helloWorld')
eval_js返回最后一个表达式的值:
import pyduktape2 context = pyduktape2.DuktapeContext() hello_world = context.eval_js("var helloWorld = 'Hello, World!'; helloWorld") print hello_world
可以在javascript中无缝地使用python对象和函数 代码。不过,有一些限制:任何python可调用都可以 仅用作函数,其他属性不能 已访问。基元类型(int、float、string、none)转换为 等效的javascript原语。下面的代码演示如何 从javascript与python对象交互:
import pyduktape2 class Hello(object): def __init__(self, what): self.what = what def say(self): print('Hello, {}!'.format(self.what)) context = pyduktape2.DuktapeContext() context.set_globals(Hello=Hello) context.eval_js("var helloWorld = Hello('World'); helloWorld.say();")
同样,您可以在python中使用javascript对象。你可以 使用特殊方法new来实例化对象:
import pyduktape2 context = pyduktape2.DuktapeContext() Hello = context.eval_js(""" function Hello(what) { this.what = what; } Hello.prototype.say = function () { print('Hello, ' + this.what + '!'); }; Hello """) hello_world = Hello.new('World') hello_world.say()
您可以使用javascript中的python列表和dict,以及viceversa:
import pyduktape2 context = pyduktape2.DuktapeContext() res = context.eval_js('[1, 2, 3]') for item in res: print(item) context.set_globals(lst=[4, 5, 6]) context.eval_js('for (var i = 0; i < lst.length; i++) { print(lst[i]); }') res = context.eval_js('var x = {a: 1, b: 2}; x') for key, val in res.items(): print(key, '=', val) res.c = 3 context.eval_js('print(x.c);') context.set_globals(x=dict(a=1, b=2)) context.eval_js(""" var items = x.items(); for (var i = 0; i < items.length; i++) { print(items[i][0] + ' = ' + items[i][1]); } """) context.set_globals(x=dict(a=1, b=2)) context.eval_js('for (var k in x) { print(k + ' = ' + x[k]); }')