简体   繁体   中英

import nim seq in python

th.nim

import nimpy
import nimongo.bson
import nimongo.mongo


proc fib(): seq[Bson] {.exportpy.} =
  var m: Mongo = newMongo()
  let connected = m.connect()
  let col = m["feed"]["post"]
  var docs: seq[Bson]
  for document in col.find(%*{}).items():
    docs.add(document)

  return docs

main.py

import nimporter
import th

h = th.fib()
for item in h:
    print(item)

and in nimporter module at line 123 i added two compile parameters

'-d:nimOldCaseObjects', #because of an error
'--bound_checks:off', #because of an error

Output:

<capsule object NULL at 0x7f1975a47ae0>
<capsule object NULL at 0x7f1975a77d50>
<capsule object NULL at 0x7f1975a77f60>
<capsule object NULL at 0x7f19759488a0>
<capsule object NULL at 0x7f1975948840>
...

how can i get a data structure like dict or json in python?

PyCapsules are defined here . You are receiving Bson ref objects in a capsule at your python code, and if I'm understanding it correctly, they are C pointers. You could modify your code to return strings, or any other type that's not a ref object , so it works:

import nimpy
import nimongo / [bson, mongo]

proc fib*: seq[string] {.exportpy.} =
  let m = newMongo()
  if m.connect():
    let col = m["feed"]["post"]

    for document in col.find(%*{}).items():
      result.add($document)

In python:

import nimporter
import th

for item in th.fib():
    print(item)

To further illustrate, the following procs return a Table from Nim to Python: the first is a Table , and the second a ref Table .

import tables
import nimpy


proc objs*: Table[string, string] {.exportpy.} =
  {"Nim": "Awesome"}.toTable

proc refs*: TableRef[string, string] {.exportpy.} =
  {"Nim": "Awesome"}.newTable

import nimporter
import script as th


for k, v in th.objs().items():
    print(k, "is", v)

for k, v in th.refs().items():
    print(k, "is", v)

Only the first works, and the second is receiving a PyCapsule that you probably didn't expect:

Nim is Awesome
Traceback (most recent call last):
  File "script.py", line 8, in <module>
    for k, v in th.refs().items():
TypeError: 'PyCapsule' object is not iterable

you need to translate the bson object you get into something useable in Python world. Since nimpy converts json happily into Python dicts, it makes sense to do the conversion in Nim.

Unfortunately nimongo doesn't implement a bson-json conversion, a proper answer would be to write that proc, but here's a placeholder answer that works, by decoding the bson to a string, and then encoding that as json.

th.nim

import nimpy,nimongo/bson
from json import parseJson,JsonNode
#it's important here not to import the whole of json, as %* clashes

proc toJson*(bs:Bson):JsonNode = 
  parseJson($bs)

proc fib(): seq[JsonNode] {.exportpy.} =
  var docs = @[%*{
    "double": 5436.5436,
    "stringkey": "stringvalue",
    "document": {
      "double": 5436.5436,
      "key": "value"
    },
    "array": [1, 2, 3],
    "int32": 5436'i32,
    "int64": 5436,
  }]
  for doc in docs:
    result.add(doc.toJson)

output

{'double': 5436.5436, 'stringkey': 'stringvalue', 'document': {'double': 5436.5436, 'key': 'value'}, 'array': [1, 2, 3], 'int32': 5436, 'int64': 5436}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM