Egy ahhoz hasonló környezetre vágyom, mint ami a Google Colab-ban is van, Python3-ra – vagy ahogy a bash is intézi a source-olást (. script).
Leginkább az kellene, hogy amikor lefuttatok két szkriptet, az elsőnek a változóit, eredményeit ne felejtse el a parancssor, amikor indítom a másikat. ( https://realpython.com/run-python-scripts/ – ebben utánanéztem, hogy az "import" effélét csinál, de mégis, mikor lefuttattam (importtal) az első részt, és indítottam volna a másodikat, NameError: name 'valami' is not defined jött. Tehát elfelejtett mindent, amit az első futamban csinált.
Ennek az egésznek az a motivációja, hogy az első rész sokáig fut, a másodikat viszont többször szükséges lehet újraindítani (és ez utóbbi nem fut sokáig, de támaszkodik az első eredményeire).
Hozzászólások
Szia,
én csinálnék egy osztályt, ahol az első szkript és a második szkript külön függvényként szerepelnének és első modul futtatása után a kimenetet változóba mentve a második bármikor elérheti. Nem tudom mennyire fedi ez így le a use case-t.
Hááát, ha nem lesz más megoldás, akkor ez is egy lehetőség.
De igazából kíváncsi is vagyok, hogy tényleg ennyire töketlen-e ez a python környezet, hogy egy ilyen trivialitást nem tud workaround nélkül megcsinálni, ami a bash-ben ennyi?
. script1
. script2
aztán ebben hogy indítgatod újra az elsőtől függetlenül a másodikat?
Jogos, inkább így pontosítanám, hogy mindez parancssorból történik:
. script1
./script2
./script2
./script2
./script2
Azaz python3-ban effélét hittem:
>>> import script1
>>> import script2
vmi hiba
>>> import script2
Bár már mondták a többiek, de ha ilyesmi módon akarod használni, akkor neked valami interaktív shell szerű kell. Vannak az ilyen nagyon fancyk, mint Jupiter (sose használtam, de elvileg ilyesmikre jó), vagy egy sima repl. Maga a python is megy, csak kissé fapados, én ptpython-t szoktam használni, az egész fancy. Aztán ott lehet tolni, hogy
Ha nem akarsz átadással bohóckodni, akkor a scripteket talán meg lehet úgy tákolni, hogy bele tudjon polluteolni az interpreter namespace-ébe, de az valami csúnyaság lesz.
Illetve azt még azért hadd jegyezzem meg, hogy elég humoros, amikor 'szar a python' fennhanggal kéred számon egy programnyelvtől, hogy belül nem működik interaktív shell szerűen. Ráadásul nem veszed észre, hogy a shellben így átadni max lapos listákat meg hasheket lehet, azért érzed, hogy az kicsit más.
Ps: van xonsh is, lehet, hogy az még handybb ilyen usecasekre, én még nem mertem kipróbálni, mert a való élethez sajtreszelőnek tűnt
Igen, elismerem, hogy volt egy ilyen kicsengése a gondolatmenetemnek, hogy 'szar a python', de igazából ezt csak bosszankodásomban írtam.
Ha jobban belegondolok, igazából a régi vágású gondolkodásomban van a hiba, vagyis a nem-eléggé-objektumorientált szkriptelő stílusomban.
A pythont nagyon sokra tartom, még akkor is, ha nehezen áll rá a fejem.
Azt azért továbbra is fenntartom, hogy jólesne egy olyan python utasítás, ami egyenértékű azzal, hogy "interaktív shellbe (editorból kimásolás után) beragasztok egy kódrészletet és hadd fusson, utána pedig ne feledd az eredményeket". Azaz, mint ami a bash-ben a source.
Mar leirtam, hogy a bash source parancsa csak azert mukodik, mart bash a shelled es onnan sourceolsz, nem azert mukodik, mert a bash okos. Ha nem bash shelt hasznalsz, maris megborult az elmeleted.
Szerintem source utasítás több shellben is van, nem a bash sajátja. De ezek szerint van olyan python környezet (lásd az alább hozzászóló kantal bejegyzését), ahol megmaradnak a változók.
Ha sourceval 'behuzol' egy filet, akkor az aktaulisan futo ertelmezo (azaz, az a shell,amiben eppen pont ott te vagy, fuggetlenul attol, hogy mi szerepel a shebangnal) fogja ertelmezi azt az allomanyt, felteve persze, ha van benne source parancs. Ha ez a shell kompatibilis azzal a 'nyelvvel', amit a behuzott allomanyban hasznalsz, akkor le fog futni benne a dolog. De itt van peldaul a csh shell, ami ugyan ismeri a source parancsot, viszont nem erti az sh szintaxist, igy hiaba source-olsz ott be egy mas nyelvben irt scriptet, az nem fog menni.
Értem, amit írsz, de itt nyelvek keveréséről nem volt szó az én értelmezésemben. Tehát nem akartam bash-ből pythont értelmezni vagy csh-ból sh-t. Amire vágytam, az egy bármilyen-python-szerű shell, amiből több python szkriptet tudok source-olni (vagy futtatni) egymás után, s aminél nem kell bíbelődni a változók átadásával, szerializálásával.
Tehat, akkor hajlando vagy bash shell helyett, python shellt is inditani? Ha igen, akkor a CPython default shelljebol is tudsz ilyet csinalni pl igy:
exec(open("almafa.py").read())
Igeeen! :-)
Ipythonban %run progi.py
Utána eléred a változókat.
eutlantis
Kösziiii!!!
Kicsit konkrétabb kellene. Konkrétan az environment változókat szeretnéd, vagy valami beazonosítható eredményeket, vagy mit? Illetve milyen viszonyban van az első, meg a második?
Mert mintha azt szeretnéd, hogy az első lefutásának eredményét tudd sourceolni, de ilyet a bash se csinál, sourcenál kapsz új "példányt", újra fog kezdődni az élet. Az alapján amit írsz, én azt mondanám, hogy a sokáig futó szépen serializálja az eredményeit valahova.
Az első készít egy tömböt, mondjuk arr néven, és ezt szeretném a másodikban használni.
(Meg más változók is kellhetnek a script2-ben, amiknek a script1 adott értéket.)
import json
... számol ...
json.dump(első_eredmény) # kiírni fájlba
- * -
import json
első_eredmény = json.load(....) # be a fájlból
... tovább számol ...
Amit szeretnel, az teljesen logikatlan es ertelmetlen. Megpedig azert, mert kevered a dolgokat. Esetedben, amikor bash shellben vagy, akkor eppen egy interaktiv modon futo basht hasznalsz, ebben tudsz masik bash scriptet behivni (source/.). A python ennek megfelelo "analogiaja" az, ha elinditassz egy interaktiv pythont (amit vetlelenul, egyebkent itt is python shellnek hivnak), majd ebben hivod be a kesz scriptjeidet (import).
A megoldas jelen esetben az, ha az elso script eredmenyet valamilyen formaban elmented (pickle/json), majd ezt hasznalod egy masik allomanybol.
Lehet, hogy te logikátlannak és értelmetlennek látod, de számomra van benne ráció. :-)
Elfogadom, amit írtál, hogy az analógia sántít a bash shellel.
Az is valószínű, hogy a lustaság (is) beszél belőlem (illetve a szerializációtól való ódzkodás, ha nem muszáj).
A helyzet a következő módon alakult ki:
- adott egy naaagy python szkript. Fut, fut.
- az első része jó sokáig.
- utána jön a második része, és pikk-pakk lehal.
Gondoltam, nosza, vágjuk ketté, és ami sokáig fut, azt ne kelljen újra futtatgatni.
Hiszen ilyet bashben gyerekjáték... csak olló kell hozzá.
De lehet, hogy naivitás volt részemről, hogy pusztán ollóval akartam ezt megoldani.
Szia! Ha jól értem akkor neked igazából pont arra van szükséged ahogyan a Google Colab (vagy bármilyen jupyter notebook) esetén szervezni szokás a programokat:
- a hosszan futó meg a röviden futó részedet tedd egy-egy modulba (=függvényként fájlba)
- indíts egy interaktív python shellt
- import-old be a két modulodat
- az első hosszan futó függvényt hívd meg és tárold el a futási eredményt egy változóba
- ezután a második függvényt akárhányszor hivogathatod ebből az interaktív shellből
opcionális kanyar: ha a második függvény helyben módosítja az első eredményeként kapott adatokat, akkor opcionálisan érdemes lehet lemásolni azokat mielőtt hívod a második függvényt (ez a funkcionalitás lehet a második függvény elején is)
példakód:
Rendben, köszi a kidolgozott példát!
Igen, az látszik, hogy az eredeti (szép lineáris) kódot át kell alakítsam...
pickle modul?
eutlantis
Azt lehet úgy használni, hogy "szerializálj ki mindent!"? Vagy csak megadott változóneveket fogad el?
Nem tudok róla. De minden változót, ami fontos, betehetsz egy listába. Az alábbi példában a betöltést ugyanabbana sorrendben kell elvégezni, mint a dump-ot.
eutlantis
Köszi!!!
Na ma is kaptam új megoldást. Köszi.
Mi az előnye a pickle-féle sorosításnak a fentebb már írt json-féle sorosításhoz képest? Ez valami újabb szabványos adatformátum?
Őszintén szólva most nem tudom megmondani; valamikor tudtam😀
A pickle "natívabb", ezt használja az értelmező a processzek és threadek közti adatcserénél is csak nem fájlba dumpolva, hanem sztringbe (dumps). Talán összetettebb objektumokat lehet vele kezelni. (A fenti példámban a lista túl egyszerűre sikeredett.)
eutlantis
Tetszik. Az adat bson-jellegű (binary json).
Egy dologgal viszont kapásból többet tud, "multi-json"-ként viselkedik. Ha úgy tetszik, van egy fájlon/streamen belüli "json elválasztó" delimitere (0x2e) is. Itt egy szemléletes példa:
Rust modul is támogatja: https://crates.io/crates/serde-pickle, ezáltal átadható közöttük is ilyen formátumban az adat.
Eddig mindenhol formázott vagy egysoros json-okból álló adathalmazt használtam. De mostantól ezt is megjegyzem. Köszi mégegyszer.
A korábbi példám helyett ez izgalmasabb:
A fentinél elakad a json.dump, nem tetszik neki, hogy a szótárban tuple az egyik kulcs.
Jó tudni a rust-os kapcsolatról. A korábbi, a rust-ról szóló bejegyzéseid már felkeltették az érdeklődésemet:-)
eutlantis
Hmm. Nem tudom hülyeségnek tartani, de esküszöm, hogy kulcsként még nem jutott eszembe a tuple.
Jönnek a különbségek. Vajon tuple mely nyelven lehet kulcs
Python ... képlékenyen átalakulnak a típusok:
>>> d= {"A":1, (3,None): 2.5}
>>> d[3,None]
2.5
>>> d.get((3,None))
2.5
>>> d.get((3,True))
>>>
Rust a merev típusossága (azaz nem képlékenyen átformálódó) miatt sokkal keményebben játsza a csiki-csukit, de rábeszélhető.
https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gi…
Neha kenyelmes, kb. ugyanarra, amire a ritka matrix egy ertelmes koncepcio. Sokszor van 2 dimenzio->1 dimenzio osszerendeles, ahol az elemek donto tobbsege ertelmetlen, vagy valami default ertek. Ilyenkor egy {(i,j):val} ertekekbol allo dictionary jol johet. (es ebben nem csak szam lehet a scipy-os sparse matrixokkal ellentetben)
A strange game. The only winning move is not to play. How about a nice game of chess?
A JSON eleg jo, de korlatozott az abrazolasi kepessege. Van par primitiv (egesz vagy tizedestort szam, string), ezekbol epitheto lista meg dictionary. A pickle ennel bonyolultabb dolgokat is el tud tarolni, binaris (ennek minden elonyevel es hatranyaval), es a vegen ugyanaz az objektum esik ki belole. Pl. ha van egy tobbdimenzios numpy tombod, akkor JSON eseten ebbol elobb listak listajat kell csinalnod, mert a JSON nem ismeri a numpy tomb tipust. Aztan kerdes, hogy a - mondjuk 64 bites - floating point ertekedet hany tizedesre akarod kerekiteni, mert itt ugye veszitesz a pontossagabol. Aztan betolteskor ugyanez visszafele. Pickle eseten ugyanugy elteheted, mint barmi mast, esszeru korlatokkal (egy TCP/IP socketet hiaba csomagolnal be es tennel el, masik gepen masnap eloszedve mar csak szakadt kapcsolatot kapnal). Pandas dataframe-et is megalkotsz, elteszed (ott meg kulon wrappert is kapsz, hogy a 2 sor helyett 1 sor kelljen a pickle-be csomagolashoz), es utana hasznalhatod amikor csak kell. (hosszabb adattisztitashoz kenyelmes, ha a felkesz eredmenyt el tudod tenni)
Ha zavar, hogy binaris, base64-en keresztultolhato az eredmeny - bar kezzel nem nyulnek bele a JSONnel ellentetben, de pl. DB-be mentettem mar el igy objektumokat stringesitve. (lett volna mas lehetoseg is, elonyoket es hatranyokat figyelembe veve ez bizonyult itt a legjobbnak)
A strange game. The only winning move is not to play. How about a nice game of chess?
Szerintem nem akarsz mindent serializalni, mert vannak beepitettek is, amit jobb bekenhagyni. Mindenesetre van egy globals() es egy locals() fuggveny, ami visszaadja, hogy milyen globalis/lokalis valtozokat lat.
A strange game. The only winning move is not to play. How about a nice game of chess?
Irsz egy blabla.py-t, amiben benne vannak a dolgaid. Ez lesz az, amit source-olsz. Utana:
Innentol elersz mindent, amit blabla-ban letrehoztal. Hasznalhatod az "import blabla" parancsot is, akkor viszont blabla.akarmi neven tudod elerni amit abban a file-ban felvettel. (en utobbit jobban szeretem, ugy nem lesz nevutkozes)
Blabla termeszetesen lehet masik konyvtarban is:
Esetleg importalod a sys-t, es utana a sys.path-ot beallitod, hogy hol keresse:
(a sys.path egy sima lista, szoval ugyanugy kezelheted, ahogy egy listat szokas)
ujabb szerk: Ez persze a cimben szereplo source-olos problemara ad megoldast. Hosszu futashoz valoban nem ez kell, hanem a pickle.
Azt egyebkent ugy szoktam hasznalni, hogy listaba/tuple-be teszem amit ki akarok menteni, es utana szinten listat/tuple-t olvasok belole:
A strange game. The only winning move is not to play. How about a nice game of chess?