-
Notifications
You must be signed in to change notification settings - Fork 2
Introducere
Python este un limbaj de programare dinamic, de nivel înalt, ce pune accent pe expresivitatea și înțelegerea ușoară a codului. Sintaxa sa permite implementări echivalente cu alte limbaje în mai puține linii de cod. Datorită acestui fapt, Python este foarte răspândit atât în programarea de aplicații, cât și în zona de scripting.
Limbajul facilitează mai multe paradigme de programare, în special paradigma imperativa (C) și pe cea orientată pe obiecte (Java). Spre deosebire de C, Python nu este un limbaj compilat, ci interpretat. Acest fapt are atât avantaje, cât și dezavantaje. Pe de-o parte, Python este mai lent decât C. Pe de altă parte, aplicațiile Python sunt foarte ușor de depanat, codul putând fi ușor inspectat în timpul rulării. De asemenea, este foarte ușor de experimentat cu mici fragmente de cod folosind interpretorul Python.
Sintaxa este gândită în așa fel încât programele Python să fie ușor de citit.
Acest lucru este obținut prin folosirea de cuvinte în locul semnelor (de exemplu, and
în loc de &&
) și prin includerea indentării în limbaj. Astfel, în Python nu se folosesc acolade (ca în C/C++, Java), ci blocurile de cod se delimitează prin indentare. Programele Python sunt, de multe ori, foarte aproape de o "implementare" echivalentă în pseudocod.
Exemplu:
# Write your code below!
print("Welcome to Python!")
Limbajul Python este interpretat, nu compilat. Asta înseamnă că programele Python sunt transformate într-un limbaj intermediar. Acest lucru permite codului să fie ușor de portat pe diverse sisteme de operare și arhitecturi hardware.
Codul este executat linie cu linie. Astfel, dacă - de exemplu - apelăm o funcție care nu există, vom primi un mesaj de eroare abia când se încearcă executarea liniei respective. Erorile de sintaxă sunt raportate însă înainte de rularea programului.
Pentru a exersa sintaxa și elementele de bază ale limbajului, vom folosi direct interpretorul Python.
Python poate fi instalat conform ghidului de aici.
Interpretorul seamănă foarte mult cu o linie de comanda (cmd.exe, bash). Prompt-ul (>>>
) apare când se așteaptă input din partea utilizatorului. După ce este introdusă o instrucțiune, aceasta este evaluată și dacă există output, este afișat în continuare, începând cu o linie nouă. Expresiile sunt evaluate și afișate.
>>> # Comentariile incep cu '#'si tot ce se afla la dreapta va fi ignorat
>>> 3 # 3 este o expresie - este evaluata si se afiseaza rezultatul
3
>>> 2 + 4 # alta expresie
6
>>> a = 3 # aceasta instructiune declara variabila a in sesiunea curenta si ii atribuie valoarea 3
>>> a # introducand o expresie, i se va afisa valoarea
3
>>> a + 4
7
>>> a = 'hi' # a poate lua orice valoare
>>> a
'hi'
>>>
Pentru experimente simple, putem folosi interpretorul interactiv, dar dacă scriem programe complexe, e mai comod să ne salvăm programul într-un fișier, și să îl executăm de acolo. Fișierele sursă Python au extensia .py
. Pentru a executa un fișier Python putem folosi comanda:
$ python hello.py user
Se executa hello.py cu argumentul user
. Nu sunt necesari pași suplimentari pentru compilare.
#!/usr/bin/python
# prima data importam modulele necesare
# modului sys este util pentru accesarea variabilelor
import sys
print('Hello, ', sys.argv[1])
# Argumentele primite se gasesc in sys.argv[index]
# sys.argv[0] este numele scriptului si poate fi ignorat in acest caz
# sys.argv[1] este următorul argument primit
Exemplu de apel:
$ python hello.py 'Iulia'
Hello, Iulia
$ ./hello.py 'Iulia' # functioneaza doar pentru fisiere executabile (Unix)
Hello, Iulia
În Python nu este necesară folosirea de ;
la sfârșitul unei instrucțiuni. Folosim o linie pentru fiecare instrucțiune. În cazul în care dorim să scriem mai multe instrucțiuni pe aceeași linie, putem folosi ;
ca în exemplu:
>>> a = 2; b = 3; c = 4
O caracteristică a limbajului Python este faptul că indentarea cu spații poate influența rezultatul unei secvențe de cod. Acest lucru poate părea neobișnuit pentru începători, dar este foarte logic. Recomandarea oficială PEP8 pentru indentare este de 4 spații.
Cum am spus în secțiunea Lucrul cu interpretorul, Python este un limbaj dinamic și nu lucrăm direct cu tipuri. Ele există, 2
este în continuare int
, dar programatorul nu trebuie să specifice acest lucru.
a = 3 # declaram variabila a, cu valoarea 3
b = 4 # declaram variabila b, cu valoarea 4
suma = a + b # declaram variabila suma, cu valoarea sumei dintre a si b
Din acest motiv este foarte util să dăm nume relevante variabilelor pentru a ne aminti rolul lor. De multe ori putem avea erori dacă uităm tipul fiecărei variabile.
În continuare vom prezenta o scurtă descriere a celor mai folosiți operatori. Pentru o listă completă consultați acest document.
-
+
- adunare -
-
- scădere -
*
- înmulțire -
/
- împărțire -
%
- operatorul modulo;a % b
întoarce restul împărțirii luia
lab
-
**
- exponent;a ** b
este echivalent cua
la putereab
-
//
- împărțire în care rezultatul se trunchiază; de exemplu:9.0 // 2.0 = 4.0
, în timp ce9.0 / 2.0 = 4.5
Similar cu alte limbaje, aceștia sunt: ==
, !=
, <>
, <
, >
, <=
, >=
.
Cel mai des folosit este operatorul simplu de atribuire =
, care atribuie variabilei din stânga lui valoarea expresiei din dreapta lui.
Pe lângă acesta, s-au definit o serie de operatori compuși astfel: operator aritmetic + operatorul simplu de atribuire. Exemplu:
-
+=
- realizează o adunare și o atribuire, astfel:a += b
este echivalent cua = a + b
-
%=
- asignează operandului din stânga restul împărțirii acestuia la operandul din dreapta, astfel:a %= b
este echivalent cua = a % b
Similar funcționează și operatorii: -=
, *=
, \=
, **=
, //=
.
De remarcat că acești operatori sunt foarte aproape de limbajul natural, ceea ce face codul ușor de citit și înțeles:
-
and
- operatorul ȘI -
or
- operatorul SAU -
not
- operatorul negație
Verifică dacă un element aparține, respectiv nu aparține, unei secvențe: in
, respectiv not in
.
Exemplu:
>>> 'ab' in 'abecedar'
True
>>> 1 not in [1, 2, 3]
False
Cele mai comune tipuri numerice în Python sunt int
și float
.
2 # int
2.0 # float - similar cu double in C
Tipul int
nu are valori minime și maxime, poate fi reprezentată orice valoare întreagă.
Se numesc True și False, și putem executa operații logice cu ele:
>>> 1 < 2
True
>>> 1 > 2
False
>>> True and 1 < 2
True
>>> True and 1 > 2
False
>>> False or True
True
Spre deosebire de C, Python oferă suport built-in pentru string-uri. Șirurile date ca intrare pentru o operație sunt immutable, deci nu pot fi modificate și orice operațiune returnează string-uri noi. Pot fi scrise cu ghilimele simple sau duble la alegere.
"hello, world"
Pentru a extinde un string pe mai multe linii putem folosi fie backslash, fie ghilimelele triple.
my_str = 'prima linie \
a doua linie'
sau
my_str = """prima linie
a doua linie"""
String-urile pot fi accesate aleator:
>>> 'hello'[2]
"l"
Nu există tipul "caracter". Se folosesc string-uri cu un element, sau reprezentările numerice directe. Se poate trece de la caracter la număr și invers folosind funcțiile ord
și chr
.
>>> ord('a')
97
>>> chr(97)
'a'
String-urile pot fi concatenate folosind operatorul +
:
"hello, " + "world" == "hello, world"
Totuși, sintaxa următoare nu este corectă:
age = 5
"I am " + age + " years old" != "I am 5 years old"
Putem folosi:
"I am " + str(age) + " years old"
Lungimea unui șir o aflăm cu functia len()
.
>>> len("Iulia")
5
Alte funcţii utile cu stringuri.
Putem construi string-uri folosind operatorul %
, asemănător funcțiilor printf
și sprintf
din biblioteca standard C:
>>> "numar: %d" % 13
'numar: 13'
>>> "string: %s" % "foo"
'string: foo'
Listele sunt echivalentul vectorilor dinamici din STL (din C++). Ele sunt similare cu string-urile.
Se pot declara folosind sintaxa:
a = [1, 2, 3]
Pot fi concatenate cu +:
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
Pot fi accesate în funcție de index:
>>> [1, 2, 3, 4][2]
3
Se pot adaugă elemente la sfârșit folosind metoda append
:
>>> a = [1, 2, 3]
>>> a
[1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
Este de remarcat faptul că elementele unei liste nu trebuie să fie de același tip.
>>> a = [1, "foo"]
>>> a.append(["bar", 22])
>>> a
[1, 'foo', ['bar', 22]]
Dicționarele sunt asocieri cheie - valoare, asemănător hashmap-ului din STL. Cheile pot fi string-uri, numere, sau alte obiecte nemodificabile (de exemplu nu putem folosi o listă drept cheie). Valorile pot fi orice.
>>> alex = {"nume": "Alex", "rol": "student", "an": 3}
>>> alex["nume"]
'Alex'
>>> alex["an"]
3
>>> alex["an"] = 4
>>> alex["an"]
4
>>> alex
{'nume': 'Alex', 'rol': 'student', 'an': 4}
>>> alex["medie"] = 10
>>> alex
{'nume': 'Alex', 'rol': 'student', 'medie': 10, 'an': 4}
Condiționalele sunt expresii care întorc o valoare A sau o valoare B în funcție de valoarea de adevăr a unei expresii. Precum în majoritatea limbajelor de programare, și în Python există structura if/else.
if conditie:
succes()
else:
esec()
numar_esecuri += 1
După cum se observă, este folosit :
în loc de {
, iar blocurile de cod ce vor fi executate pe ramurile respective sunt indentate. De asemenea, nu este nevoie de paranteze în jurul condiției verificate.
În acest caz, trebuie să avem grija la indentare:
a = 1
if conditie:
a = 2
b = a + 2
nu este echivalent cu:
a = 1
if conditie:
a = 2
b = a + 2
De multe ori, în C/C++ se folosește un șablon precum:
if (conditie1) {
functie1();
} else if (conditie2) {
functie2();
} else if (conditie3) {
functie3();
} else {
functie4();
}
Echivalentul Python este:
if conditie1:
functie1()
elif conditie2:
functie2()
elif conditie3:
functie3()
else:
functie4()
După cum se observă, nu există else if
în Python, ci elif
. Acest șablon de cod este aproape identic cu o structură switch
. În Python nu există switch
, folosindu-se blocuri if-elif-else
.
În Python o condiție se poate exprima și astfel:
x = true_value if condition else false_value
Pentru a repeta un bloc de cod avem două opțiuni: while și for.
Structura while din Python este la fel ca cea din C, ținând cont de diferențele de sintaxă:
while conditie:
instructiune1
instructiune2
For este diferit în Python. Sintaxa este:
for elem in colectie:
instructiune1
instructiune2
elem
va lua pe rând ca valoare fiecare element din colecție.
Astfel, codul C:
int i;
for (i = 0; i < 4; i++) {
instr;
}
este echivalent cu:
for i in [0, 1, 2, 3]:
instr
Pentru a obține o listă cu numerele de la A la B (fără B), se poate folosi range(A, B)
. Dacă A este 0, putem folosi direct range(B)
.
Astfel, codul devine:
for i in range(4):
instr
Funcția range primește și un parametru opțional ce reprezintă diferența între doua valori consecutive.
De exemplu, pentru a obține:
int i;
for (i = 0; i < 10; i += 2) {
...
}
Folosim:
for i in range(0, 10, 2):
...
Instrucțiunea print
afișează mesaje la standard output. Putem afișa valoarea oricărei expresii:
>>> print(1 + 1)
2
>>> print("hello world")
'hello world'
>>> a = 10
>>> print(a)
10
Python are funcții, la fel ca majoritatea celorlalte limbaje de programare. În continuare vom discuta despre particularitățile modului în care sunt create și utilizate funcțiile în Python.
O funcție se declară folosind cuvântul cheie def
astfel:
>>> def fibonacci(n):
Documentarea unei funcții se face printr-un doc string
:
>>> def fibonacci(n):
... """Afiseaza seria fibonacci pana la n."""
Corpul unei funcții se scrie indentat.
>>> def fibonacci(n):
... """Afiseaza seria Fibonacci pana la n."""
... a, b = 1, 1
... while a < n:
... print(a)
... a, b = b, a + b
>>> fibonacci
<function fibonacci at 0x0000000001ECBAC8>
>>> fibonacci(5)
1
1
2
3
Definirea funcțiilor trebuie să se facă înainte ca acestea să fie folosite. Dacă o funcție este apelată înainte să fie definită, interpretorul va da o eroare de tipul NameError
.
Funcțiile pot să returneze și o valoare. Mai jos este un exemplu cu afișarea șirului Fibonacci în mod recursiv.
>>> def fibonacci2(n):
... """Afiseaza al n-lea numar Fibonacci, în mod recursiv."""
... if n > 2:
... return fibonacci2(n-1) + fibonacci2(n-2)
... return 1
>>> fibonacci2
<function fibonacci2 at 0x0000000002CF7DD8>
>>> fibonacci2(5)
8
- Funcțiile care nu folosesc
return
pentru a întoarce o valoare, întorc totuși valoareaNone
. - Dacă se folosește doar intrucțiunea
return
, valoarea întoarsă este totNone
.
>>> print(fibonacci(0))
None
Funcțiile pot fi folosite în orice expresie (cum am văzut în exemplul anterior), sau apelate dintr-o altă funcție:
>>> def print_fibonacci(n):
... print("Al", n, "-lea numar Fibonacci este", fibonacci2(n))
>>> print_fibonacci(5)
Al 5 -lea numar Fibonacci este 5
Să pornim de la următorul exemplu:
>>> x = 0
>>> y = 0
>>> def inc(x):
... y = x + 1
... return y
>>> inc(5)
6
>>> print(x, y)
0 0
Variabilele declarate într-o funcție și argumentele acesteia, sunt numite variabile locale funcției. Variabilele definite la nivel global sunt numite variabile globale. Într-o funcție, putem să folosim valorile variabilelor globale:
>>> pi = 3.14
>>> def aria_cercului(r):
... return pi * r * r
>>> aria_cercului(1)
3.14
Variabilele globale pot fi modificate la nivel global. Însă, pentru a putea fi modificate într-o funcție, ele trebuie declarate folosind cuvântul cheie global
:
>>> numar_apelari = 0
>>> def patrat(x):
... global numar_apelari
... numar_apelari += 1
... return x * x
>>> patrat(4)
16
>>> numar_apelari
1
După cum am văzut în secțiunea precedentă, funcțiile pot primi argumente. Pentru funcția fibonacci(n)
, n
este un argument. Mai jos sunt câteva exemple de funcții (fără argumente, cu mai multe argumente).
>>> def printeaza_fara_argument():
... print("Aceasta functie nu primeste argumente.")
>>> printeaza_fara_argument()
Aceasta functie nu primeste argumente.
>>> def printeaza_trei_argumente(arg1, arg2, arg3):
... print("Argumentele pe care functia le-a primit, sunt in ordine: ", arg1, arg2, arg3)
>>> printeaza_trei_argumente(1, "doi", 1 + 2)
Argumentele pe care functia le-a primit, sunt in ordine: 1 doi 3
Unele argumentele pot să aibă și valori implicite. Acest lucru le face practic opționale, deoarece Python va folosi valoarea implicită atunci când nu primește o altă valoare pentru acel argument.
>>> def incrementeaza(x, cu_cat=1):
... print(x + cu_cat)
>>> incrementeaza(10)
11
>>> incrementeaza(10, 5)
15
Exemplele de mai sus au folosit toate argumente poziționale. Există de asemenea posibilitatea folosirii așa-numitelor argumente cu nume (keyword arguments) de forma nume_argument=valoare
.
>>> def scadere(x, y):
... return x - y
>>> scadere(5, 3)
2
>>> scadere(x=5, y=3)
2
>>> scadere(y=3, x=5)
2
>>> scadere(5, y=3)
2
Argumentele poziționale trebuie să le preceadă întotdeauna pe cele cu nume.
>>> scadere(y=2, 5)
SyntaxError: non-keyword arg after keyword arg
Nu se acceptă argumente cu alte nume decât argumentele funcției.
>>> scadere(5, z=2)
TypeError: scadere() got an unexpected keyword argument 'z'
Niciun argument nu poate primi o valoare mai mult de o dată.
>>> scadere(5, 3, x=4)
TypeError: scadere() got multiple values for keyword argument 'x'
*args
și **kwargs
ne permit să trimitem un număr variabil de parametri unei funcții.
>>> def printeaza_argumente_variabile(arg1, *args):
... print("primul argument: ", arg1)
... for arg in args: # ia pe rand fiecare valoare din lista args
... print("un alt argument din *args: ", arg)
>>> printeaza_argumente_variabile(1, "ana", "are", "mere")
primul argument: 1
un alt argument din *args: ana
un alt argument din *args: are
un alt argument din *args: mere
>>> lista = ["al doilea", 3]
>>> printeaza_argumente_variabile("argumentul 1", *args) # despachetarea unei liste de argumente
primul argument: argumentul 1
un alt argument din *args: arg2
un alt argument din *args: 3
*args
este practic lista de argumente suplimentare ale funcției.
**kwargs
ne permite să transmitem un număr variabil de parametri cu nume unei funcții. Dacă *args
se comportă ca o listă de argumente, **kwargs
este un dicționar, unde numele argumentului este cheia, iar valoarea argumentului este valoarea asociată cheii în dicționar:
>>> def printeaza_argumente_variabile(**kwargs):
... if kwargs is not None:
... for key, value in kwargs.iteritems():
... print(key, " == ", value)
>>> printeaza_argumente_variabile(prenume="Ion", nume="Popescu")
nume == Popescu
prenume == Ion
>>> kwargs = {"nume": "Popescu", "prenume": "Ion", "localitate": "Bucuresti"} # despachetarea unui dicționar
>>> printeaza_argumente_variabile(**kwargs)
nume == Popescu
localitate == Bucuresti
prenume == Ion