Manipulate Python code in Moonbit
sudo apt-get update && sudo apt-get install python3.13 python3.13-devbrew install python@3.13# Verify Python version
python3 --versionmoon update
moon add Kaida-Amethyst/python{
"import": [
"Kaida-Amethyst/python"
]
}typealias @python.(PyInteger, PyList, PyTuple)
fn main {
// It's equivalent to `nums = [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]`
let nums = [1L, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
let py_nums = nums.map(PyInteger::from) |> PyList::from
println(py_nums) // Output: [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
// It's equivalent to `import collections`
guard @python.pyimport("collections") is Some(collections)
// It's equivalent to `from collections import Counter`
guard collections.get_attr("Counter") is Some(PyCallable(counter))
let args = PyTuple::new(1)
args.. set(0, py_nums)
// It's equivalent to `cnt = Counter(nums)`
guard counter.invoke?(args~) is Ok(Some(cnt))
guard cnt is PyDict(cnt)
// `print(cnt)`
println(cnt) // Output: Counter({4: 4, 3: 3, 1: 2, 2: 2})
}moon run main --target nativefrom collections import Counter
l = [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
print(Counter(l)) # Counter({4: 4, 3: 3, 1: 2, 2: 2})sudo apt-get update && sudo apt-get install python3.13 python3.13-devbrew install python@3.13# 验证Python版本
python3 --versionmoon update
moon add Kaida-Amethyst/python{
"import": [
"Kaida-Amethyst/python"
]
}typealias @python.(PyInteger, PyList, PyTuple)
fn main {
// It's equivalent to `nums = [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]`
let nums = [1L, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
let py_nums = nums.map(PyInteger::from) |> PyList::from
println(py_nums) // Output: [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
// It's equivalent to `import collections`
guard @python.pyimport("collections") is Some(collections)
// It's equivalent to `from collections import Counter`
guard collections.get_attr("Counter") is Some(PyCallable(counter))
let args = PyTuple::new(1)
args.. set(0, py_nums)
// It's equivalent to `cnt = Counter(nums)`
guard counter.invoke?(args~) is Ok(Some(cnt))
guard cnt is PyDict(cnt)
// `print(cnt)`
println(cnt) // Output: Counter({4: 4, 3: 3, 1: 2, 2: 2})
}moon run main --target nativefrom collections import Counter
l = [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
print(Counter(l)) # Counter({4: 4, 3: 3, 1: 2, 2: 2})pub trait IsPyObject {
obj(Self) -> PyObject
obj_ref(Self) -> PyObjectRef
type_name(Self) -> String
}pub suberror PyRuntimeError {
TypeMismatchError
IndexOutOfBoundsError
KeyIsUnHashableError
InVokeError
}impl Show for PyRuntimeErrorpub struct PyBool {
// private fields
}impl IsPyObject for PyBoollet t = PyBool::from(true);
inspect(t, content="True")t = True
print(t) # Output: Truelet t = PyBool::from(true);
let f = PyBool::from(false);
assert_false(t.is_false());
assert_true(f.is_false());let t = PyBool::from(true);
let f = PyBool::from(false);
assert_true(t.is_true());
assert_false(f.is_true());let t = PyBool::from(true);
let f = t.not();
assert_true(f.is_false());pub struct PyCallable {
// private fields
}impl IsPyObject for PyCallableimpl Show for PyCallablefn PyCallable::invoke(self : PyCallable, args? : PyTuple, kwargs? : PyDict, print_err? : Bool) -> PyObjectEnum? raise PyRuntimeErrorpub struct PyDict {
// private fields
}impl IsPyObject for PyDictlet dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));
inspect(dict.get("one").unwrap(), content="PyInteger(1)")
inspect(dict.get("two"), content="Some(PyFloat(2.0))")
inspect(dict.get("four"), content="None")let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));
inspect(dict.items(), content="[('one', 1), ('two', 2.0), ('three', True)]")let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));
inspect(dict.keys(), content="[\'one\', \'two\', \'three\']")d = { 'one': 1, 'two': 2.0, 'three': True }
dict_keys = d.keys()
print(dict_keys) # Output: dict_keys(['one', 'two', 'three'])let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyString::from("three"));
assert_eq(dict.len(), 3);let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));
inspect(dict, content="{\'one\': 1, \'two\': 2.0, \'three\': True}")d = { 'one': 1, 'two': 2.0, 'three': True }
print(d) # Output: {'one': 1, 'two': 2.0, 'three': True}let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));
inspect(dict["one"], content="PyInteger(1)")
inspect(dict["two"], content="PyFloat(2.0)")
inspect(dict["three"], content="PyBool(True)")let dict = PyDict::new()
dict["one"] = PyInteger::from(1);
dict["two"] = PyFloat::from(2.0);
dict["three"] = PyBool::from(true);
inspect(dict, content="{\'one\': 1, \'two\': 2.0, \'three\': True}")d = dict()
d['one'] = 1
d['two'] = 2.0
d['three'] = Truelet dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));
inspect(dict, content="{\'one\': 1, \'two\': 2.0, \'three\': True}")d = dict()
d['one'] = 1
d['two'] = 2.0
d['three'] = Truefn[K : IsPyObject, V : IsPyObject] PyDict::setByObj(self : PyDict, key : K, val : V) -> Unit raise PyRuntimeErrorlet dict = PyDict::new()
dict
..setByObj(PyInteger::from(1), PyInteger::from(1))
..setByObj(PyInteger::from(2), PyInteger::from(4))
..setByObj(PyInteger::from(3), PyInteger::from(9))
inspect(dict, content="{1: 1, 2: 4, 3: 9}")d = dict()
d[1] = 1
d[2] = 4
d[3] = 9
print(d) # Output: {1: 1, 2: 4, 3: 9}let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));
inspect(dict.values(), content="[1, 2.0, True]")d = { 'one': 1, 'two': 2.0, 'three': True }
dict_values = d.values()
print(dict_values) # Output: dict_values([1, 2.0, True])pub struct PyFloat {
// private fields
}impl IsPyObject for PyFloatlet f = @python.PyFloat::from(3.5);
inspect(f, content="3.5")pub struct PyInteger {
// private fields
}impl IsPyObject for PyIntegerlet i = @python.PyInteger::from(42);
inspect(i, content="42")let i = @python.PyInteger::from(42);
assert_eq(i.to_double(), 42.0);pub struct PyList {
// private fields
}impl IsPyObject for PyListlet list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));
inspect(list, content="[1, 2.0, \'hello\']")list = []
list.append(1)
list.append(2.0)
list.append("hello")
print(list) # Output: [1, 2.0, 'hello']let arr: Array[&IsPyObject] = Array::new()
let one = PyInteger::from(1);
let two = PyFloat::from(2.0);
let three = PyString::from("three");
arr.push(one)
arr.push(two)
arr.push(three)
let list = PyList::from(arr);
inspect(list, content="[1, 2.0, \'three\']")let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));
inspect(list.get(0).unwrap(), content="PyInteger(1)")
inspect(list.get(1), content="Some(PyFloat(2.0))")
inspect(list.get(3), content="None")
inspect(list.get(-1), content="None")let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));
assert_eq(list.len(), 3);list = []
list.append(1)
list.append(2.0)
list.append("hello")
print(len(list)) # Output: 3let list = @python.PyList::new();
inspect(list, content="[]")
assert_eq(list.len(), 0);let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));
inspect(list[0], content="PyInteger(1)")
inspect(list[1], content="PyFloat(2.0)")
inspect(list[2], content="PyString(hello)")let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));
inspect(list, content="[1, 2.0, \'hello\']")
list[0] = @python.PyInteger::from(42);
inspect(list, content="[42, 2.0, \'hello\']")let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));
inspect(list, content="[1, 2.0, \'hello\']")
list.set(0, @python.PyInteger::from(42));
inspect(list, content="[42, 2.0, \'hello\']")pub struct PyModule {
// private fields
}impl IsPyObject for PyModulelet collections = pyimport("collections").unwrap()
guard collections.get_attr("Counter").unwrap() is PyCallable(counter)
let list = [1L, 2L, 2L, 3L, 3L, 3L].map(PyInteger::from) |> PyList::from
let args = PyTuple::new(1)
args .. set(0, list)
guard counter.invoke(args~) is Some(PyDict(cnt))
inspect(cnt, content="Counter({3: 3, 2: 2, 1: 1})")
guard cnt.obj().get_attr("total") is Some(PyCallable(total))
inspect(total.invoke().unwrap(), content="PyInteger(6)")import collections
from collections import Counter
list = [1, 2, 2, 3, 3, 3]
cnt = Counter(list)
print(cnt) # Counter({3: 3, 2: 2, 1: 1})
total = cnt.total()
print(total) # 6pub struct PyString {
// private fields
}impl IsPyObject for PyStringpub struct PyTuple {
// private fields
}impl IsPyObject for PyTuplelet tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));
inspect(tuple, content="(1, 2.0, \'three\')")
inspect(tuple.get(0).unwrap(), content="PyInteger(1)")
inspect(tuple.get(1).unwrap(), content="PyFloat(2.0)")
inspect(tuple.get(2).unwrap(), content="PyString(three)")
inspect(tuple.get(3), content="None")tuple = (1, 2.0, "three")
print(tuple) # Output: (1, 2.0, 'three')
print(tuple[0]) # Output: 1
print(tuple[1]) # Output: 2.0
print(tuple[2]) # Output: threelet tuple = PyTuple::new(3)
assert_eq(tuple.len(), 3);let tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));
inspect(tuple, content="(1, 2.0, \'three\')")let tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));
inspect(tuple[0], content="PyInteger(1)")
inspect(tuple[1], content="PyFloat(2.0)")
inspect(tuple[2], content="PyString(three)")let tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));
inspect(tuple, content="(1, 2.0, \'three\')")let tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));
inspect(tuple, content="(1, 2.0, \'three\')")pub enum PyType {
PyInteger
PyFloat
PyBool
PyString
PyTuple
PyList
PyDict
PyModule
PyCallable
PyClass
}let os = @python.pyimport("os")
assert_true(os is Some(_))fn strip_quot(s : String) -> Stringlet s = "\'os\'"
inspect(@python.strip_quot(s), content="os")Manipulate Python code in Moonbit