libpython-clj2.require
Namespace implementing requiring python modules as Clojure namespaces. This works via scanning the module for metadata and dynamically building the Clojure namespace.
import-python
(import-python)
Loads python, python.list, python.dict, python.set, python.tuple, and python.frozenset.
require-python
(require-python req)
(require-python req & reqs)
Basic usage
(require-python 'math) (math/sin 1.0) ;;=> 0.8414709848078965
(require-python 'math :as maaaath)
(maaaath/sin 1.0) ;;=> 0.8414709848078965
(require-python 'math 'csv) (require-python 'math :as pymath 'csv)) (require-python 'math :as pymath 'csv :as py-csv) (require-python 'concurrent.futures) (require-python 'concurrent.futures :as fs) (require-python '(concurrent futures :as fs))
(require-python '[requests :refer get post])
(requests/get "https//www.google.com") ;;=> <Response 200> (get "https//www.google.com") ;;=> <Response 200>
In some cases we may generate invalid arglists metadata for the clojure compiler. In those cases we have a flag, :no-arglists that will disable adding arglists to the generated metadata for the vars. Use the reload flag below if you need to force reload a namespace where invalid arglists have been generated.
(require-python '[numpy :refer linspace :no-arglists :as np])
If you would like to bind the Python module to the namespace, use the :bind-ns flag.
(require-python 'requests :bind-ns true) or (require-python 'requests :bind-ns)
Use with custom modules
For use with a custom namespace foo.py while developing, you can use:
(require-python 'foo :reload)
NOTE: unless you specify the :reload flag, ..: the module will NOT reload. If the :reload flag is set, ..: the behavior mimics importlib.reload
Setting up classpath for custom modules
Note: you may need to setup your PYTHONPATH correctly. WARNING: This is very handy for local REPL development, ..: if you are going to AOT classes, ..: refer to the documentation on codegen ..: or your AOT compilation will fail. If your foo.py lives at /path/to/foodir/foo.py, the easiest way to do it is:
(require-python :from "/path/to/foodir" 'foo) ;; or (require-python "/path/to/foodir" 'foo) ;; or (require-python {:from "/path/to/foodir"} 'foo)
as you prefer.
Additionally, if you want to keep the namespacing as you have it in Python, you may prefer to use a relative import starting from a location of your choosing. If your os.getcwd() => /some/path/foo, and your directory structure looks something like:
/some $ tree . └── path ├── baz │ └── quux.py └── foo └── bar.py
(require-python :from "path" 'baz.quux :as quux :from "path/foo" 'bar)
is perfectly acceptable. It probably makes the most
sense to keep you style consistent, but you can mix
and match as you see fit between
You may also stack several require-pythons under one path:
(require-python {:from "dir-a"} 'a 'b 'c {:from "dir-b"} 'e.f 'g {:from "dir-c} 'hi.there)
Other options more in keeping with traditional PYTHONPATH management include:
(require-python 'sys) (py/call-attr (py/get-attr sys "path") "append" "/path/to/foodir")
Another option is
(require-python 'os) (os/chdir "/path/to/foodir")
prefix lists
For convenience, if you are loading multiple Python modules with the same prefix, you can use the following notation:
(require-python '(a b c)) is equivalent to (require-python 'a.b 'a.c)
(require-python '(foo [bar :as baz :refer qux])) is equivalent to (require-python '[foo.bar :as baz :refer qux])
(require-python '(foo [bar :as baz :refer qux] buster)) (require-python '[foo.bar :as baz :refer qux] 'foo.buster))
For library developers
If you want to intern all symbols to your current namespace, you can do the following --
(require-python 'math :refer :all)
However, if you only want to use those things designated by the module under the all attribute, you can do
(require-python 'operators :refer :*)