Skip to content

Commit 91c7ca0

Browse files
committed
Adding pickle example to usage doc
1 parent ceb4e5e commit 91c7ca0

File tree

1 file changed

+85
-9
lines changed

1 file changed

+85
-9
lines changed

topics/Usage.md

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ INFO: Reference thread starting
7575

7676
This dynamically finds the python shared library and loads it using output from
7777
the python3 executable on your system. For information about how that works,
78-
please checkout the code
78+
please checkout the code
7979
[here](https://github.com/cnuernber/libpython-clj/blob/master/src/libpython_clj/python/interpreter.clj#L30).
8080

8181

@@ -308,36 +308,36 @@ user> (py/$.. numpy random shuffle)
308308

309309
##### New sugar (fixme)
310310

311-
`libpython-clj` offers syntactic forms similar to those offered by
312-
Clojure for interacting with Python classes and objects.
311+
`libpython-clj` offers syntactic forms similar to those offered by
312+
Clojure for interacting with Python classes and objects.
313313

314314
**Class/object methods**
315315
Where in Clojure you would use `(. obj method arg1 arg2 ... argN)`,
316-
you can use `(py. pyobj method arg1 arg2 ... argN)`.
316+
you can use `(py. pyobj method arg1 arg2 ... argN)`.
317317

318318
In Python, this is equivalent to `pyobj.method(arg1, arg2, ..., argN)`.
319319
Concrete examples are shown below.
320320

321321
**Class/object attributes**
322-
Where in Clojure you would use `(.- obj attr)`, you can use
322+
Where in Clojure you would use `(.- obj attr)`, you can use
323323
`(py.- pyobj attr)`.
324324

325-
In Python, this is equivalent to `pyobj.attr`.
325+
In Python, this is equivalent to `pyobj.attr`.
326326
Concrete examples shown below.
327327

328328
**Nested attribute access**
329329
To achieve a chain of method/attribute access, use the `py..` for.
330330

331-
```clojure
332-
(py.. (requests/get "http://www.google.com")
331+
```clojure
332+
(py.. (requests/get "http://www.google.com")
333333
-content
334334
(decode "latin-1"))
335335
```
336336
(**Note**: requires Python `requests` module installled)
337337

338338
**Examples**
339339

340-
```clojure
340+
```clojure
341341
user=> (require '[libpython-clj.python :as py :refer [py. py.. py.-]])
342342
nil
343343
user=> (require '[libpython-clj.require :refer [require-python]])
@@ -418,3 +418,79 @@ please refer to the datatype library [documentation](https://github.com/techasce
418418

419419
Just keep in mind, careless usage of zero copy is going to cause spooky action at a
420420
distance.
421+
422+
423+
### Pickle
424+
425+
Speaking of numpy, you can pickle python objects and transform the result via numpy and dtype
426+
to a java byte array and back:
427+
428+
429+
```clojure
430+
user> (require '[libpython-clj2.python :as py])
431+
nil
432+
user> (py/initialize!)
433+
Sep 03, 2022 11:23:34 AM clojure.tools.logging$eval5948$fn__5951 invoke
434+
INFO: Detecting startup info
435+
Sep 03, 2022 11:23:34 AM clojure.tools.logging$eval5948$fn__5951 invoke
436+
INFO: Startup info {:lib-version "3.9", :java-library-path-addendum "/home/chrisn/miniconda3/lib", :exec-prefix "/home/chrisn/miniconda3", :executable "/home/chrisn/miniconda3/bin/python3", :libnames ("python3.9m" "python3.9"), :prefix "/home/chrisn/miniconda3", :base-prefix "/home/chrisn/miniconda3", :libname "python3.9m", :base-exec-prefix "/home/chrisn/miniconda3", :python-home "/home/chrisn/miniconda3", :version [3 9 1], :platform "linux"}
437+
Sep 03, 2022 11:23:34 AM clojure.tools.logging$eval5948$fn__5951 invoke
438+
INFO: Prefixing java library path: /home/chrisn/miniconda3/lib
439+
Sep 03, 2022 11:23:35 AM clojure.tools.logging$eval5948$fn__5951 invoke
440+
INFO: Loading python library: python3.9
441+
Sep 03, 2022 11:23:35 AM clojure.tools.logging$eval5948$fn__5951 invoke
442+
INFO: Reference thread starting
443+
:ok
444+
user> (def data (py/->python {:a 1 :b 2}))
445+
#'user/data
446+
user> (def pickle (py/import-module "pickle"))
447+
#'user/pickle
448+
user> (def bdata (py/py. pickle dumps data))
449+
#'user/bdata
450+
user> bdata
451+
b'\x80\x04\x95\x11\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x01a\x94K\x01\x8c\x01b\x94K\x02u.'
452+
user> (def np (py/import-module "numpy"))
453+
#'user/np
454+
user> (py/py. np frombuffer bdata :dtype "int8")
455+
[-128 4 -107 17 0 0 0 0 0 0 0 125 -108 40
456+
-116 1 97 -108 75 1 -116 1 98 -108 75 2 117 46]
457+
user> (require '[libpython-clj2.python.np-array])
458+
nil
459+
user> (def ary (py/py. np frombuffer bdata :dtype "int8"))
460+
#'user/ary
461+
user> (py/->jvm ary)
462+
#tech.v3.tensor<int8>[28]
463+
[-128 4 -107 17 0 0 0 0 0 0 0 125 -108 40 -116 1 97 -108 75 1 -116 1 98 -108 75 2 117 46]
464+
user> (require '[tech.v3.datatype :as dt])
465+
nil
466+
user> (dt/->byte-array *2)
467+
[-128, 4, -107, 17, 0, 0, 0, 0, 0, 0, 0, 125, -108, 40, -116, 1, 97, -108, 75, 1,
468+
-116, 1, 98, -108, 75, 2, 117, 46]
469+
user> (require '[tech.v3.tensor :as dtt])
470+
nil
471+
user> (dtt/as-tensor *2)
472+
nil
473+
user> (def bdata *3)
474+
#'user/bdata
475+
user> bdata
476+
[-128, 4, -107, 17, 0, 0, 0, 0, 0, 0, 0, 125, -108, 40, -116, 1, 97, -108, 75, 1,
477+
-116, 1, 98, -108, 75, 2, 117, 46]
478+
user> (type bdata)
479+
[B
480+
user> (def tens (dtt/reshape bdata [(dt/ecount bdata)]))
481+
#'user/tens
482+
user> (def pdata (py/->python tens))
483+
#'user/pdata
484+
user> pdata
485+
[-128 4 -107 17 0 0 0 0 0 0 0 125 -108 40
486+
-116 1 97 -108 75 1 -116 1 98 -108 75 2 117 46]
487+
user> (py/python-type *1)
488+
:ndarray
489+
user> (def py-ary *2)
490+
#'user/py-ary
491+
user> (def py-bytes (py/py. py-ary tobytes))
492+
#'user/py-bytes
493+
user> (py/py. pickle loads py-bytes)
494+
{'a': 1, 'b': 2}
495+
user>
496+
```

0 commit comments

Comments
 (0)