Apa itu
PyMini ialah penterjemah subset Python yang ditulis dalam Swift dan terbina dalam papan kekunci. Setiap panel dan setiap tindakan anda berjalan padanya. Ia membaca bentuk Python yang anda sudah kenal, dan bahasa yang sama berkhidmat sama ada skrip melukis antara muka atau menulis semula satu perkataan.
# an action: text in, text out
def transform(text):
return text.upper()
# a panel: a view, and what a tap does
def view(state):
return button("Shout", "shout")
def on_action(action, state):
insert(context()["word"].upper())
return stateMengapa menggunakannya
Kami membina PyMini kerana Clink memerlukan cara untuk orang menulis skrip bagi papan kekunci mereka sendiri, dan tiada apa yang kami temui muat di dalamnya. Namun tiada apa pun padanya yang terikat pada papan kekunci, jadi kini ia sumber terbuka sebagai pakej Swift tersendiri, untuk mana-mana apl yang mahu membenarkan penggunanya menulis sedikit Python.
Ia bukan CPython, dan tidak membenamkannya. Sambungan papan kekunci mendapat sepersekian daripada memori sebuah apl, dan binari serta timbunan CPython akan menghabiskan belanjawan itu sebelum skrip anda sempat berjalan. PyMini ialah beberapa ratus kilobait Swift, tanpa kebergantungan binari.
Gunakannya di mana sahaja pengguna mahukan logik mereka sendiri: penukaran teks dalam apl penulisan, peraturan dalam apl senarai tugasan atau belanjawan, formula, automasi, mod permainan, atau sistem plugin untuk apl yang mempunyai komuniti. Ramai orang sudah tahu sedikit Python, jadi tiada bahasa baharu untuk diajar, dan skrip ialah teks biasa yang boleh anda simpan, segerakkan dan kongsi seperti tetapan lain.
import PyMini
let py = PyRuntime(modules: ["math", "json", "re"])
// your app, as a Python function
py.define("shout") { call in
try call.argument(0, as: String.self).uppercased()
}
// a script one of your users wrote
try py.load("""
def tidy(text):
return shout(" ".join(text.split()))
""")
try py.call("tidy", " hello there ") // HELLO THERE| Panggilan | Apa yang dilakukan |
|---|---|
import PyMini | Tiada kebergantungan dan tiada apa yang perlu dibungkus sendiri. Tambah pakej Swift dan ia berjalan pada iOS 15, macOS 12, tvOS 15, watchOS 8 dan visionOS 1 atau lebih baharu. |
py.define("shout") { call in ... } | Ciri apl anda menjadi fungsi dan modul Python. Argumen tiba sebagai jenis Swift, dan apa yang anda pulangkan kembali kepada skrip sebagai nilai Python. |
PyLimits(steps: 200_000) | Setiap panggilan berjalan dengan belanjawan langkah, dan kehabisannya ialah ralat yang tidak boleh ditangkap oleh mana-mana skrip. while True yang cuai berakhir dengan mesej, bukan apl yang beku. |
PyRuntime(modules: ["math"]) | Skrip tidak mendapat fail, rangkaian atau proses. Ia hanya mencapai fungsi yang anda takrifkan dan modul standard yang anda biarkan hidup. |
py.call(hook: "on_open") | Panggil skrip apabila sesuatu berlaku dalam apl anda. Cangkuk yang tidak ditakrifkan oleh skrip akan dilangkau, jadi setiap cangkuk boleh menjadi pilihan. |
catch let error as PyError | Ralat kembali dengan nama pengecualian Python dan nombor baris, sedia untuk ditunjukkan kepada orang yang menulis skrip itu. |
import sys | sys.version menyebut nama penterjemah dan versinya, dan perintah pymini mencetak baris yang sama. Skrip boleh melaporkan versi yang dibawa oleh apl di sekelilingnya. |
Kod sumber, rujukan bahasa dan ujian ada di GitHub.
Apa yang dijanjikannya
Tiada sistem fail, tiada rangkaian dan tiada proses yang boleh dicapai oleh skrip: kotak pasir itu ialah bentuk penterjemah, bukan senarai perkara yang ditolaknya. import ialah satu-satunya pintu keluar, dan ia terbuka kepada senarai pendek ruang nama yang hanya mengira. Selain itu semuanya memakan langkah. Setiap ungkapan, setiap pusingan gelung, setiap langkah ungkapan biasa dan setiap baris JSON membelanjakan satu daripada 2,000,000, dan rentetan serta senarai dihadkan sambil membesar.
Boleh diimport dalam panel yang dikongsi
jsonmathrandomresystime
Belanjawan itu tidak boleh ditangkap. Klausa except menangkap KeyError, tetapi bukan pengguguran yang menamatkan gelung terlepas kawalan, kerana menangkapnya itulah caranya skrip terlepas kawalan akan terus berjalan.
Log perubahan
Setiap versi PyMini, yang terbaharu dahulu, dan apa yang ditambah olehnya.
PyMini 2.0
Versi pertama boleh menjadikan satu perkataan huruf besar dan menyusun grid butang. Versi kedua ialah bahasa untuk menulis program kecil, dan panel yang menjawab ketikan, bukan sekadar membawa satu jawapan tetap.
| Contoh | Apa yang berubah |
|---|---|
[word for word in words if word] | Pemahaman senarai, lambda, tupel, set, dan try / except / finally / raise. |
f"{total:,.2f}" | Penukaran f-string dan spesifikasi format penuh, dikongsi dengan str.format dan format(). |
f"""Hello {name}""" | Rentetan dalam tanda petik tiga, rentetan mentah, dan f-string yang merentas beberapa baris. |
import math, random, time, json, re | Lima ruang nama, dan tiada yang lain, semuanya tulen. |
re.sub(r"\s+", " ", text) | Ungkapan biasa pada enjin Clink sendiri, yang membelanjakan belanjawan langkah yang sama. |
on_action(action, value, state) | Panel mengendalikan ketikannya sendiri, menyimpan keadaan sebenar, dan mempunyai sebelas kawalan lagi. |
replace(len(word), word.upper()) | Skrip boleh meminta papan kekunci bertindak, dan membaca apa yang ada di sekeliling kursor. |
Current sentence | Tindakan membaca mana-mana bahagian medan, bukan sekadar perkataan dan apa yang mendahuluinya. |
import re
def initial():
return {"words": []}
def view(state):
top = sorted(set(state["words"]), key=lambda w: -len(w))[:3]
return vstack([text(f"{len(state['words']):,} words", mono=True)]
+ [row(w, detail=f"{len(w)}") for w in top])
def on_open(state):
state["words"] = re.findall(r"\w+", context()["before"])
return statePyMini 1.0
Versi pertama. Tindakan menukar satu rentetan kepada rentetan lain, dan panel hanyalah beberapa kawalan yang butangnya menaip rentetan tetap atau menetapkan nilai.
| Contoh | Apa yang berubah |
|---|---|
def transform(text): | int, float, str, bool, None, list dan dict, dengan if, while, for, serta def dengan argumen lalai dan argumen kata kunci. |
f"{n} words" | f-string tanpa spesifikasi format, serta pengindeksan dan penghirisan dengan indeks negatif. |
sorted(text.split()) | 24 fungsi terbina dalam dan kaedah biasa untuk str, list dan dict. |
button("+", set={"count": 1}) | Teks, butang, medan, tindanan dan grid. Butang hanya boleh menaip teks atau menetapkan keadaan. |
while True: | Tiada import langsung, belanjawan langkah untuk setiap skrip, dan had setakat mana rentetan dan senarai boleh membesar. |
Ke mana seterusnya
Keseluruhan permukaan bahasa, perbendaharaan kata panel, dan pembina yang menulis kedua-duanya tanpa anda menaip satu baris pun.
Tindakan ›Panel ›Plugin ›Pencipta ›