Elemente avansate de Python

Varianta rulabilă a fișierului curent poate fi accesată aici: Elemente avansate de Python

Funcții

Funcțiile se definesc cu ajutorul cuvântului def. Pot avea oricât de mulți parametri, și pot returna oricât de multe valori. Parametrii pot avea valori implicite, dar restricțiile de tip sunt mai mult pentru developer -- nu vor arunca erori dacă nu sunt respectate.

def f(age: int, name = "Bran") -> str:
  pass

f('Age')

Valorile implicite se află mereu la finalul listei de parametri.

Obervați cuvântul cheie pass folosit mai sus. Este o expresie vidă care poate fi utilizată în interiorul unei structuri pentru a nu arunca eroare până o completăm cu instrucțiunile dorite. O putem folosi atunci când vrem să scriem întâi headerele funcțiilor / claselor.

Clase

Clasele se definesc cu ajutorul cuvântului cheie class. Ca în orice limbaj, avem variabile statice pe care le putem apela fie la nivel de clasă, fie la nivel de instanță a clasei:

class Clasa:
  x = 10

Clasa.x

Output: 10

instanta = Clasa()
instanta.x

Output: 10

Cu ce seamănă clasele din ce ați mai făcut până acum?

...

Funcțiile din clase încep mereu cu operatorul self -- referință către clasa respectivă. Referința poate avea orice denumire, self este doar o convenție.

class Clasa:
  x = 3

  def f(self, x):
    return self.x, x

instanta = Clasa()
instanta.f(7)

Output: (3, 7)

Observă cum x și self.x sunt variabile complet separate. În Python, parametrii funcțiilor mereu sunt considerați independenți de mediul exterior, în timp ce elementele care încep cu self. sunt specifici instanței clasei respective.

Pe lângă funcțiile normale avem și o serie de funcții implicite:

  • __init__ -> inițializarea clasei (constructor)
  • __str__ -> transformarea clasei în instanță string
  • __lt__ -> definiția operatorului <
  • __le__ -> definiția operatorului <=
  • __gt__ -> definiția operatorului >

Funcțiile pot fi apelate cu denumirea lor, dar și direct, folosind simbolul respectiv.

class Clasa:
  def __init__(self, x):
    self.x = x

  def __str__(self):
    return "Valoarea clasei: " + str(self.x)

instanta = Clasa(5)
print(instanta)

Output: Valoarea clasei: 5

EXERCIȚIU

Creează o clasă cu minim 2 elemente. Creează 2 instanțe pentru noua clasă și afișeaz-o pe cea mai mare în urma comparației dintre ele.


Vom descoperi mai multe despre limbaj pe măsură ce lucrăm cu el.

Puteți găsi mai multe exemple aici: https://colab.research.google.com/drive/1Lxed6J79CsWwyrr8vpLugTmS6GMwMA-j?usp=drive_link

Sau în documentația limbajului: https://docs.python.org/3/

Regex

Un RegEx reprezintă o Expresie Regulată (codificarea unei secvențe de caractere). Poate fi folosit pentru a identifica secvențe de caractere într-un șir, pentru a înlocui secvențe sau pentru a separa un șir în funcție de diferite metrici. O secvență de căutare arată așa:

import re

txt = "The rain in Spain stays mainly in the plain"
x = re.search("Spain", txt)

if x:
  print("Cuvântul există în șir")
else:
  print("Cuvântul nu există în șir")

Output: Cuvântul există în șir

Există o serie de reguli și simboluri pe care le putem folosi pentru a descrie secvența de caractere căutată. O să modificăm exemplul original pentru a ne uita la câteva exemple.

Putem pune [.] în pozițiile în care poate fi orice caracter, [^] este caracterul început de șir și [$] este caracterul pentru final de șir.

print(re.findall("Sp.in", txt))
print(re.findall("^The rain in Spain stays mainly in the plain$", txt))

Output:

['Spain']
['The rain in Spain stays mainly in the plain']

Dacă punem [+] după un caracter acela trebuie să apară minim o dată. Dacă punem [*] după un caracter, acela poate să apară de oricâte ori, chiar și 0. Simbolurile pot fi combinate: [.+] înseamnă că putem avea o listă de caractere oricât de lungă.

x = re.findall(".*ai", txt)
print(x)

Output: ['The rain in Spain stays mainly in the plai']

În loc de a folosi [.+] putem folosi secvențe specifice:

  • \d identifică o listă de cifre
  • \D - caractere care nu sunt cifre
  • \s - caracterul spațiu
  • \w - litere mici și mari, cifre și caracterul "_"

Pentru a fi și mai specifici putem folosi seturi:

  • [ar] - cel puțin unul din caracterele "a" și "r" este prezent
  • [a-n] - orice caracter lowercase din intervalul dat
  • [0-9] - putem aplica intervalele și pentru cifre
  • [a-zA-Z] - sau le putem concatena pentru a accepta caractere mai variate
  • [1-3][7-9] - două seturi unul în continuarea celuilalt funcționează ca orice alte simboluri legate. Exemplul dat caută o secvență de 2 cifre, unde prima cifră este în intervalul 1-3, iar a doua în intervalul 7-9

Putem folosi secvențele de mai sus pentru a identifica toate cuvintele care conțin șirul "ai", de exemplu:

x = re.findall("\w*ai\w", txt)
print(x)

Output: ['rain', 'Spain', 'main', 'plain']

Lista completă de reguli și simboluri se află aici: https://docs.python.org/3/library/re.html

EXERCIȚIU

Creează o funcție de preprocesare a textului: funcția va primi un șir de caractere, îl va împărți în cuvinte și va elimina toate caracterele care nu sunt litere. Modifică funcția astfel încât să păstreze cratimele din cuvinte.

txt = "M-am dus la piata - asta voiam? Vom ajunge repede, cred, acasa!"