python转js对象_将Python对象转换为PyV8的JavaScript

显然,PyV8无法正确将python列表转换为Javascript数组,这导致my_list.length返回undefined,该值将转换为None.

ctx = PyV8.JSContext()

ctx.enter()

ctx.locals.a = [{'a':1}]

print ctx.locals.a

#> [{'a': 1}]

print ctx.eval("a.length")

#> None

print ctx.eval("a[0].a")

#> 1

ctx.locals.blub = {'a':1}

print ctx.eval("blub.a")

#> 1

print ctx.eval("Object.keys(blub)")

#> a

ctx.locals.blub = {'a':[1,2,3]}

print ctx.eval("Object.keys(blub)")

#> a

print ctx.eval("blub.a")

#> [1, 2, 3]

ctx.locals.blub2 = [{'a':[1,2,3]}]

print ctx.eval("blub2")

#> [{'a': [1, 2, 3]}]

print ctx.eval("blub2.length")

#> None

print ctx.eval("Array.isArray(blub2)")

#> False

print ctx.eval("typeof(blub2)")

#> object

print ctx.eval("blub2[0].a")

#> [1, 2, 3]

print ctx.eval("typeof(blub.a)")

#> object

print ctx.eval("Array.isArray(blub.a)")

#> False

ctx.locals.blub3 = get_js_obj({'a':[1,2,3]})

ctx.locals.blub4 = get_js_obj([1,2,3])

ctx.eval("blub3.a.length")

#> 3

ctx.eval("blub4.length")

#> 3

这里是功能.

def access_with_js(ctx, route):

if len(route) == 0:

raise Exception("route must have at least one element")

accessor_string = route[0]

for elem in route[1:]:

if type(elem) in [str, unicode]:

accessor_string += "['" + elem + "']"

elif type(elem) == int:

accessor_string += "[" + str(elem) + "]"

else:

raise Exception("invalid element in route, must be text or number")

return ctx.eval(accessor_string)

def get_py_obj(ctx, obj, route=[]):

def dict_is_empty(dict):

for key in dict:

return False

return True

def access(obj, key):

if key in obj:

return obj[key]

return None

cloned = None

if isinstance(obj, list) or isinstance(obj, PyV8.JSArray):

cloned = []

temp = str(access_with_js(ctx, route)) #working around a problem with PyV8 r429

num_elements = len(obj)

for index in range(num_elements):

elem = obj[index]

cloned.append(get_py_obj(ctx, elem, route + [index]))

elif isinstance(obj, dict) or isinstance(obj, PyV8.JSObject):

cloned = {}

for key in obj.keys():

cloned_val = None

if type(key) == int:

#workaround for a problem with PyV8 where it won't let me access

#objects with integer accessors

val = None

try:

val = access(obj, str(key))

except KeyError:

pass

if val == None:

val = access(obj, key)

cloned_val = get_py_obj(ctx, val, route + [key])

else:

cloned_val = get_py_obj(ctx, access(obj, key), route + [key])

cloned[key] = cloned_val

elif type(obj) == str:

cloned = obj.decode('utf-8')

else:

cloned = obj

return cloned

def get_js_obj(ctx,obj):

#workaround for a problem with PyV8 where it will implicitely convert python lists to js objects

#-> we need to explicitely do the conversion. see also the wrapper classes for JSContext above.

if isinstance(obj, list):

js_list = []

for entry in obj:

js_list.append(get_js_obj(ctx,entry))

return PyV8.JSArray(js_list)

elif isinstance(obj, dict):

js_obj = ctx.eval("new Object();") # PyV8.JSObject cannot be instantiated from Python

for key in obj.keys():

try:

js_obj[key] = get_js_obj(ctx,obj[key])

except Exception, e:

# unicode keys raise a Boost.Python.ArgumentError

# which can't be caught directly:

# https://mail.python.org/pipermail/cplusplus-sig/2010-April/015470.html

if (not str(e).startswith("Python argument types in")):

raise

import unicodedata

js_obj[unicodedata.normalize('NFKD', key).encode('ascii','ignore')] = get_js_obj(ctx,obj[key])

return js_obj

else:

return obj

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值