16. Anexă
*********


16.1. Modul interactiv
======================

Sunt disponibile două versiuni ale *buclei* interactive *REPL (CEAR)*
(Citește-Evaluează-Afișează-Reia). Dintre ele, modalitatea clasică de
utilizare a interpretorului (de Python în terminal) este suportată de
toate platformele moderne de calcul, doar că dispune de capacități
minimale de control al elementelor introduse în linia de comandă.

Însă, atât în Windows cât și în sistemele de operare de tip Unix cu
suport pentru "curses", ne va fi pus la dispoziție, în mod predefinit,
un interpretor interactiv nou, începând cu Python 3.13. El dispune de
colorarea itemilor (în linia de comandă), de editare multi-rând, de
substituții în istoric, respectiv de modul *lipire* (de la
englezescul, ca jargon informatic, *paste*). Pentru a dezafecta
colorarea, găsiți detalii în Controlul culorilor. Tastele *funcții*
(tastele F: se accesează apăsând simultan "Fn" și "F_număr") vă vor
oferi un plus de funcționalitate. Astfel, "F1" activează  documentația
interactivă de sprijin "pydoc". "F2" vă permite să parcurgeți
istoricul liniei de comandă fără afișarea rezultatelor (execuției de
comenzi) și nici a prompturilor *>>>*, respectiv *...*. Cu "F3" se
intră în "modul lipire", ceea ce va ușura lipirea unor blocuri (mai)
consistente de cod. Pentru a ieși din acest mod (și a vă înapoia la
promptul principal), apăsați încă o dată pe tasta ("Fn" + ) "F3".

Atunci când utilizați noul interpretor de comenzi interactiv, pentru a
ieși din el trebuie să tastați fie "exit" fie "quit". Adăugarea de
paranteze (ca la operatorul de apel) este opțională.

Dacă nu vă interesează acest interpretor de comenzi interactiv, atunci
îl puteți dezafecta cu ajutorul variabilei de mediu
"PYTHON_BASIC_REPL".


16.1.1. Tratarea erorilor
-------------------------

Când survine o eroare, interpretorul va afișa atât un *mesaj de
eroare* (corespunzător) cât și conținutul *stivei de apeluri* (de la
englezescul, ca jargon informatic, *stack (back)trace*). Dacă vă
aflați în modul interactiv, atunci interpretorul revine la promptul
principal; în caz că programul provine dintr-un fișier, terminarea
execuției se va realiza cu un *cod de ieșire* nenul, aceasta după ce a
fost afișată stiva de apeluri. (Excepțiile tratate printr-o clauză
"except" dintr-o instrucțiune "try" nu vor fi considerate, în acest
context, drept erori.) Anumite erori sunt necondiționat fatale, drept
pentru care ele vor cauza ieșirea din execuție cu un cod de ieșire
nenul; printre ele se numără inconsistențele interne ale codului,
respectiv anumite situații în care se epuizează spațiul alocat în
memorie. Toate mesajele de eroare se scriu în *fluxul de eroare* (ori
*canalul de eroare*) standard; încheierea corectă a execuției unei
comenzi se scrie în *fluxul de ieșire* standard.

Tastând *caracterul de întrerupere* (de obicei, "Control"-"C" ori
"Delete") a execuției, fie la promptul primar fie la cel secundar, vom
produce oprirea introducerii de caractere de la tastatură și revenirea
la promptul primar. [1] Dacă tastăm caracterul de întrerupere în timp
ce se derulează vreo execuție de comandă, atunci va fi lansată o
excepție "KeyboardInterrupt", a cărei interceptare poate fi
proiectată, de dumneavoastră înșivă, cu ajutorul unei instrucțiuni
"try".


16.1.2. Scripturi Python executabile
------------------------------------

În sistemele Unix de tip BSD, scripturile Python pot fi transformate
în scripturi executabile direct, aidoma scripturilor interpretorului
de comenzi activ în sesiunea de terminal, prin inserarea liniei de cod

   #!/usr/bin/env python3

chiar la începutul scriptului, respectiv adăugând permisiunilor
fișierului în care ați introdus scriptul și permisiunea ca acesta să
poată fi executat (ceea ce înseamnă a-i atribui fișierului un *mod
executabil*). Evident, am presupus că variabila de mediu "PATH" din
contul dumneavoastră de utilizator conține (și) calea de acces către
interpretor. Este necesar ca simbolul bi-semn "#!" să fie așezat chiar
la începutul fișierului. Pe anumite platforme, primul rând trebuie să
se termine cu un caracter de încheiere de rând în stil Unix (adică,
"'\n'") și nu cu cele două caractere (invizibile) care desemnează, în
Windows, sfârșitul unui rând ("'\r\n'"). Nu uitați că *diezul*,
denumit, în jargon informatic, caracter *hash*, "'#'", este
întrebuințat în Python la începerea unui comentariu (de un rând).

Pentru ca un script să primească un *mod executabil*, adică pentru a i
se da *permisiunea* de a fi executat, vom folosi comanda **chmod**.

   $ chmod +x scriptul_meu.py

În sistemele Windows nu există acest "mod executabil". Instalatorul de
Python va realiza automat asocierea fișierelor ".py" cu "python.exe",
așa că, printr-un clic dublu pe  un (simbol grafic al unui) fișier
Python, acesta va rula ca script. Dacă facem uz de extensia ".pyw" (în
locul lui ".py"), atunci fereastra terminalului, care apare la orice
execuție de script, va fi suprimată.


16.1.3. Fișierul de pornire pentru sesiunea interactivă
-------------------------------------------------------

Atunci când utilizați Python-ul în modul interactiv, este convenabil
să aveți la îndemână un set de comenzi tipice, care să fie executate
ori de câte ori porniți interpretorul. Puteți realiza așa ceva
atribuindu-i unei variabile de mediu cu numele "PYTHONSTARTUP" drept
valoare numele fișierului în care ați introdus setul respectiv de
comenzi. Un atare procedeu seamănă cu cel datorită căruia preparați
conținutul fișierului de configurare (la nivel de cont de utilizator)
".profile" al interpretoarelor de comenzi din sistemele Unix.

Fișierul (de pornire; de la englezescul, ca jargon informatic,
*startup file*) va fi citit doar când deschideți o sesiune de lucru
interactiv, nu și atunci când Python-ul își citește comenzile dintr-un
fișier, și nici atunci când "/dev/tty" este sursa explicită a
comenzilor (fișier care, altminteri, se comportă precum o sesiune
interactivă). Execuția comenzilor din fișier va avea loc în același
spațiu de nume unde se execută comenzile date interactiv, deci
obiectele definite ori importurile făcute de comenzile din fișier vor
putea fi utilizate fără *nume calificate* în timpul sesiunii
interactive. De asemeni, puteți schimba promptul principal  "sys.ps1"
și promptul secundar "sys.ps2" în acest fișier de pornire.

Dacă doriți să fie citit și un fișier de pornire adițional, situat în
directorul curent, atunci puteți realiza acest lucru introducând în
fișierul de pornire global un fragment de cod aidoma acestuia: "if
os.path.isfile('.pythonrc.py'): exec(open('.pythonrc.py').read())". De
asemeni, dacă sunteți interesați să întrebuințați fișierul de pornire
într-un script, atunci va fi nevoie să îi adăugați acelui script un
fragment de cod asemănător celui care urmează:

   import os
   numele_fișierului = os.environ.get('PYTHONSTARTUP')
   if numele_fișierului and os.path.isfile(numele_fișierului):
       with open(numele_fișierului) as obiectul_fișier:
           fișierul_de_pornire = obiectul_fișier.read()
       exec(fișierul_de_pornire)


16.1.4. Module de personalizare
-------------------------------

Python-ul ne pune la dispoziție două *ancore* (de la englezescul, ca
jargon informatic, *hook*) pentru a-l personaliza: sitecustomize
(personalizare la nivel de *sistem*, adică  *(on-)site* sau *la fața
locului*) și usercustomize (personalizare la nivel de *utilizator*).
Pentru a observa funcționarea personalizării, începem prin a găsi
calea de acces către directorul pachetelor disponibile *la fața
locului* pentru utilizator. Astfel, vom rula codul Python de mai jos:

   >>> import site
   >>> site.getusersitepackages()
   'C:\Users\nume_de_utilizator\AppData\Roaming\Python\Python313\site-packages'

Calea de acces fiind găsită, vom crea un fișier denumit
"usercustomize.py" în directorul respectiv și vom introduce în fișier
comenzile dorite. Existența acestui fișier va influența toate
invocările Python-ului, cu excepția situației în care pornirea se va
face cu opțiunea "-s", opțiune care dezactivează importurile automate.

Ancora sitecustomize funcționează la fel, doar că fișierul ei va fi
creat de către unul din administratorii sistemului dumneavoastră de
calcul și plasat într-unul din directoarele care fac parte din lista
directoarelor (globale ale) pachetelor instalate la nivel de *sistem*,
însă tot *la fața locului* (listă găsită cu "site.getsitepackages()"),
acest fișier "sitecustomize.py" fiind importat înaintea celui
corespunzând ancorei usercustomize. A se vedea documentația modulului
"site" pentru mai multe detalii.

-[ Note de subsol ]-

[1] O anumită defecțiune din pachetul GNU Readline ar putea să
    împiedice aceasta.
