12 Tajni Trikova u Pythonu Koji će Vas Pretvoriti u Pro Programera
Table of Contents
- Ključne Tačke
- Uvod
- 1. Monkeys-Patching Builtins
- 2. Funkcijska Overloading bez @overload
- 3. Dinamičko Umetanje Koda s exec i AST
- 4. weakref - Reference bez Vlasništva
- 5. Protokol Deskriptora
- 6. Thread-Safe Brojači uz collections.Counter
- 7. Import Hooks
- 8. Kreiranje Neizmjenjivih Rečnika sa MappingProxyType
- 9. Time Travel Debagovanje
- 10. Deljena Memorija između Procesa
- 11. Prilagođene getattr na Modulima
- 12. Speeds Hacks sa slots
- Često Postavljana Pitanja (FAQ)
Ključne Tačke
- Upoznajte se s 12 naprednih tehnika u Pythonu koje mogu unaprijediti kvalitetu i efikasnost vašeg koda.
- Ove tehnike uključuju razne metode manipulisanja, optimizacije i debagovanja koje koriste čak i iskusni programeri.
- Ovaj vodič pruža praktične primjere kodova kako bi vam pomogao da brzo implementirate naučeno.
Uvod
Python je jedan od najpopularnijih programskih jezika na svetu, koristeći se u različitim domenima kao što su web razvoj, analitika podataka, veštačka inteligencija i još mnogo toga. Bez obzira na to koliko dugo pišete kod u Pythonu, uvek postoje nove i zanimljive tehnike koje možete naučiti. Čak i iskusni programeri često su iznenađeni moćnim funkcijama koje je Python u stanju da ponudi. U ovom članku bićemo fokusirani na 12 naprednih trikova koji će vam pomoći da kod izgledate profesionalno i optimizovano, čak i ako ste novi u ovom jeziku.
1. Monkeys-Patching Builtins
Jedna od najuzbudljivijih, ali možda i najopasnijih tehnika u Pythonu je monkey-patching. Ova metoda vam omogućava da prepravite ugrađene funkcije tokom izvršavanja programa. Na primer, ako želite da promenite način na koji funkcija print radi, možete to uraditi ovako:
import builtins
_real_print = print
def custom_print(*args, **kwargs):
_real_print("🚀", *args, **kwargs)
builtins.print = custom_print
print("Pozdrav, Svete!")
Ova tehnika je veoma korisna za debugging, ali je važno napomenuti da je ne preporučuje u produkcionom kodu bez dubinskog razumevanja onoga što radite.
2. Funkcijska Overloading bez @overload
Python ne podržava overloading funkcija nativno, ali uz pomoć functools.singledispatch, možete simulirati ovu funkcionalnost. Ovo je korisno kada želite da pišete različite implementacije za različite tipove podataka.
from functools import singledispatch
@singledispatch
def process(arg):
raise NotImplementedError("Nepodržani tip")
@process.register
def _(arg: int):
return f"Celobrojni {arg * 2}"
@process.register
def _(arg: str):
return f"String {arg.upper()}"
print(process(5)) # Celobrojni 10
print(process("hej")) # String HEY
3. Dinamičko Umetanje Koda s exec i AST
Zamislite da možete generisati i izvršiti Python kod u runtime-u. To je moguće s modulima ast i exec.
import ast
code = "x = 2 + 3"
tree = ast.parse(code)
compiled = compile(tree, filename="<ast>", mode="exec")
exec(compiled)
print(x) # 5
Ova tehnika može biti korisna za situacije koje zahtijevaju runtime transformaciju koda.
4. weakref - Reference bez Vlasništva
“weakref” omogućava referencu na objekt bez zadržavanja njegovog postojanja u memoriji. Ova tehnika se često koristi u caching sistemima ili kada želite izbjeći ciklične reference.
import weakref
class Data:
pass
obj = Data()
weak = weakref.ref(obj)
print(weak()) # <__main__.Data object>
del obj
print(weak()) # None
5. Protokol Deskriptora
Dekoratora za svojstva (@property) je samo sintaktički šećer iznad deskriptora. Kreiranje vlastitog deskriptora može vam pomoći da u potpunosti razumijete strukture podataka u Pythonu.
class Celsius:
def __init__(self, temp=0):
self._temp = temp
def get_temp(self):
return self._temp
def set_temp(self, value):
if value < -273.15:
raise ValueError("Ispod apsolutne nule!")
self._temp = value
temperature = property(get_temp, set_temp)
t = Celsius()
t.temperature = 25
print(t.temperature)
6. Thread-Safe Brojači uz collections.Counter
U višedretvenim okruženjima, standardni brojači mogu postati problematični. Koristeći threading.Lock, možemo osigurati da su naši brojači thread-safe.
import threading
from collections import Counter
counter = Counter()
lock = threading.Lock()
def safe_increment(key):
with lock:
counter[key] += 1
threads = [threading.Thread(target=safe_increment, args=("python",)) for _ in range(100)]
[t.start() for t in threads]
[t.join() for t in threads]
print(counter) # Counter({'python': 100})
7. Import Hooks
Python omogućava da presreo importe tokom izvršavanja, što može biti korisno za alate kao što su pytest i IPython.
import sys
class ImportInterceptor:
def find_spec(self, name, path, target=None):
if name == "math":
print("Intercepted import of math!")
return None
sys.meta_path.insert(0, ImportInterceptor())
import math
8. Kreiranje Neizmjenjivih Rečnika sa MappingProxyType
Ako želite da kreirate rečnik koji se ne može menjati, možete koristiti MappingProxyType.
from types import MappingProxyType
data = {"a": 1, "b": 2}
frozen = MappingProxyType(data)
print(frozen["a"]) # 1
# frozen["a"] = 99 # ❌ TypeError
9. Time Travel Debagovanje
Možete „zakačiti“ svaku liniju koda koju Python izvršava, što vam omogućava da kreirate svoj vlastiti debager.
import sys
def tracer(frame, event, arg):
if event == "line":
print(f"Executing line {frame.f_lineno} in {frame.f_code.co_name}")
return tracer
sys.settrace(tracer)
def test():
x = 1
y = x + 2
return y
test()
10. Deljena Memorija između Procesa
Zaboravite spore redove, sa multiprocessing.shared_memory, možete deliti sirovu memoriju između procesa.
from multiprocessing import shared_memory
import numpy as np
a = np.array([1, 2, 3, 4])
shm = shared_memory.SharedMemory(create=True, size=a.nbytes)
b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
b[:] = a[:] # Share data
print(b) # [1 2 3 4]
shm.close()
shm.unlink()
11. Prilagođene getattr na Modulima
Definisanjem __getattr__ na nivou modula, možete dinamički obrađivati nepoznate atribute.
# mymodule.py
def __getattr__(name):
if name == "magic":
return 42
raise AttributeError(f"No attribute {name}")
# main.py
import mymodule
print(mymodule.magic) # 42
12. Speeds Hacks sa slots
Korišćenje __slots__ može dramatično smanjiti potrošnju memorije. U velikim OOP kodnim bazama, ovo može biti značajno korisno.
class A:
__slots__ = ("x",)
class B(A):
__slots__ = ("y",)
b = B()
b.x, b.y = 1, 2
print(b.x, b.y) # 1 2
Često Postavljana Pitanja (FAQ)
Koji su glavni benefiti ovih trikova?
Ove tehnike poboljšavaju modularnost, sigurnost i efikasnost koda, a takođe mogu pomoći u smanjenju grešaka tokom razvoja.
Mogu li koristiti ove trikove u produkciji?
Mnoge od ovih tehnika, poput monkey-patching-a ili exec-instrukcija, treba koristiti s oprezom u produkcionim okruženjima. Preporučljivo je prvo testirati kako bi ste izbegli nepredviđene probleme.
Gdje mogu naučiti više o Pythonu?
Postoji mnogo resursa, uključujući kurseve na platformama kao što su Coursera, Udacity i različite video tutorijale na YouTube-u.
Da li je Python najbolji jezik za početnike?
Python se često preporučuje početnicima zbog svoje čitljivosti i jednostavnosti. Takođe je široko korišćen u različitim industrijama, što omogućava studentima i novim programerima mnoge mogućnosti.
Kako mogu nastaviti unapređivati svoje veštine?
Vežbajte redovno, učestvujte u hackathonima, doprinosite open-source projektima i povežite se sa drugim programerima putem online zajednica ili lokalnih meetupa.
istaknuti članci