Mi ez

A PyMini a Python egy részhalmazát értelmezi, Swiftben íródott, és a billentyűzet része. Minden saját paneled és minden saját műveleted ezen fut. Azt a Pythont olvassa, amelyet már ismersz, és ugyanaz a nyelv szolgál akkor is, ha a szkript felületet rajzol, és akkor is, ha egy szót ír át.

# 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 state
Egy nyelv, két szerződés: a művelethez transform(text), a panelhez view(state).

Miért érdemes használni

Azért készítettük a PyMinit, mert a Clinknek kellett egy mód arra, hogy bárki szkriptekkel bővíthesse a saját billentyűzetét, és semmi, amit találtunk, nem fért bele egy billentyűzetbe. Billentyűzetekhez viszont semmi sem köti, ezért mostantól nyílt forráskódú, önálló Swift-csomag, bármely alkalmazásnak, amely szeretné, hogy a felhasználói írhassanak egy kis Pythont.

Ez nem CPython, és nem is ágyazza be. Egy billentyűzetbővítmény töredékét kapja annak a memóriának, amit egy alkalmazás, és a CPython binárisa meg a kupaca elköltené ezt a keretet, mielőtt a szkripted egyáltalán elindulna. A PyMini néhány száz kilobájtnyi Swift, bináris függőségek nélkül.

Mindenhol jól jön, ahol a felhasználók saját logikát szeretnének: szövegátalakítások egy íróalkalmazásban, szabályok egy teendő- vagy költségvetés-alkalmazásban, képletek, automatizálások, játékmodok, vagy bővítményrendszer egy közösségre épülő alkalmazáshoz. Sokan tudnak már egy kicsit Pythonul, így nem kell új nyelvet tanítanod, a szkript pedig egyszerű szöveg, amelyet bármely más beállításhoz hasonlóan tárolhatsz, szinkronizálhatsz és megoszthatsz.

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
Adj a szkripteknek egy Swift-függvényt, tölts be egy szkriptet, és hívd meg.
HívásMit csinál
import PyMiniNincsenek függőségek, és semmit sem kell kézzel mellécsomagolni. Add hozzá a Swift-csomagot, és fut iOS 15, macOS 12, tvOS 15, watchOS 8 és visionOS 1 vagy újabb rendszeren.
py.define("shout") { call in ... }Az alkalmazásod funkciói Python-függvényekké és -modulokká válnak. Az argumentumok Swift-típusokként érkeznek, és amit visszaadsz, az Python-értékként jut vissza a szkripthez.
PyLimits(steps: 200_000)Minden hívás lépéskerettel fut, és ha elfogy, az olyan hiba, amelyet egyetlen szkript sem tud elkapni. Egy elhamarkodott while True üzenettel ér véget, nem lefagyott alkalmazással.
PyRuntime(modules: ["math"])A szkriptek nem kapnak fájlokat, hálózatot és folyamatokat. Csak az általad definiált függvényeket és a bekapcsolva hagyott standard modulokat érik el.
py.call(hook: "on_open")Hívj meg egy szkriptet, amikor valami történik az alkalmazásodban. Azt a hookot, amelyet a szkript nem definiált, egyszerűen átugorja, így minden hook lehet opcionális.
catch let error as PyErrorA hibák a Python-kivétel nevével és a sor számával térnek vissza, készen arra, hogy megmutasd annak, aki a szkriptet írta.
import sysA sys.version megnevezi az értelmezőt és a verziót, és a pymini parancs ugyanezt a sort írja ki. Így egy szkript meg tudja mondani, melyik változatot hordozza a körülötte lévő alkalmazás.

A forráskód, a nyelvi referencia és a tesztek a GitHubon vannak.

Mit ígér

Nincs fájlrendszer, nincs hálózat és nincs folyamat, amelyet egy szkript elérhetne: a homokozó az értelmező alakja, nem pedig a tiltott dolgok listája. Az import az egyetlen kijárat, és néhány olyan névtérre nyílik, amelyek csak számolnak. Minden más lépésekbe kerül. Minden kifejezés, minden ciklusforduló, a reguláris kifejezés minden lépése és a JSON minden sora elkölt egyet a következőből: 2 000 000, a sztringek és a listák pedig növekedés közben korlátozva vannak.

Megosztott panelben importálható

  • json
  • math
  • random
  • re
  • sys
  • time

A keretet nem lehet elkapni. Egy except ág elkapja a KeyErrort, de nem kapja el azt a megszakítást, amely véget vet egy elszabadult ciklusnak: elkapni éppen az volna a módja, hogy egy elszabadult szkript tovább fusson.

Változásnapló

A PyMini összes változata, a legújabbal kezdve, és hogy mit hozott.

PyMini 2.0

Az első változat nagybetűsíteni tudott egy szót, és gombokból rácsot rakni. A második egy nyelv, amelyen kis programot írhatsz, és egy panel, amely válaszol az érintésre ahelyett, hogy csak egy rögzítettet hordozna.

PéldaMi változott
[word for word in words if word]Listakifejezések, lambdák, rendezett n-esek, halmazok, valamint try / except / finally / raise.
f"{total:,.2f}"f-string átalakítások és teljes formátumleírók, közösen a str.format és a format() függvénnyel.
f"""Hello {name}"""Háromszoros idézőjeles és nyers sztringek, valamint több soron átnyúló f-stringek.
import math, random, time, json, reÖt névtér, és más egy sem, mindegyik tisztán számoló.
re.sub(r"\s+", " ", text)Reguláris kifejezések a Clink saját motorján, amely ugyanabból a lépéskeretből gazdálkodik.
on_action(action, value, state)A panelek maguk kezelik az érintéseiket, valódi állapotot tartanak, és tizeneggyel több vezérlőjük van.
replace(len(word), word.upper())A szkriptek kérhetik a billentyűzetet, hogy tegyen valamit, és elolvashatják a kurzor környezetét.
Current sentenceA műveletek a mező bármely szeletét olvassák, nem csak a szót és az azt megelőző részt.
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 state
Panel, amely elolvassa, amit írtál, megszámolja, és kilistázza a leghosszabb szavakat.

PyMini 1.0

Az első változat. Egy művelet egy sztringből egy másikat csinált, egy panel pedig néhány vezérlőből állt, amelyek gombjai rögzített szöveget írtak be vagy beállítottak egy értéket.

PéldaMi változott
def transform(text):int, float, str, bool, None, list és dict, továbbá if, while, for, valamint def alapértelmezett és kulcsszavas argumentumokkal.
f"{n} words"Formátumleíró nélküli f-stringek, valamint indexelés és szeletelés negatív indexekkel.
sorted(text.split())24 beépített függvény és a str, a list és a dict szokásos metódusai.
button("+", set={"count": 1})Szöveg, gombok, mezők, sorok, oszlopok és egy rács. Egy gomb szöveget írhatott be vagy állapotot állíthatott, mást nem.
while True:Egyáltalán nem volt import, minden szkriptnek volt lépéskerete, és a sztringek meg a listák növekedése korlátos volt.

Merre tovább

A teljes nyelvi felület, a panelek szókincse, és egy építő, amely mindkettőt megírja anélkül, hogy egy sort is begépelnél.

Műveletek ›Panelek ›Bővítmények ›Műhely ›
Letöltés az App Store-ból