Quando si considera se utilizzare le lezioni nel codice Python, è importante valutare i benefici e i contesti in cui sono più appropriati. Le classi sono una caratteristica chiave della programmazione orientata agli oggetti (OOP) e possono fornire chiari vantaggi in termini di organizzazione, riusabilità e incapsulamento. Tuttavia, non tutti i problemi richiedono OOP.
Quando usare le lezioni
Incapsulamento e astrazione
- Incapsulamento. Le lezioni ti consentono Bundle Information (attributi) e metodi (funzioni) che operano sui dati in un’unica unità. Questo aiuta a mantenere insieme dati e comportamenti correlati.
- Astrazione. Le lezioni possono nascondere i dettagli di implementazione complessi ed esporre solo le parti necessarie attraverso i metodi pubblici.
Riusabilità
- Componenti riutilizzabili. Le classi possono essere rappresentate più volte, consentendo di creare componenti riutilizzabili che possono essere utilizzati in numerous parti dell’applicazione.
Ereditarietà e polimorfismo
- Eredità. Le classi consentono di creare nuove classi in base a quelle esistenti, riutilizzare il codice e ridurre la ridondanza.
- Polimorfismo. Le lezioni ti consentono di definire i metodi in modo story da loro può essere usato in modo intercambiabileMiglioramento della flessibilità e dell’integrazione.
Funzione statale usando le classi
L’uso di una classe è un modo più esplicito per gestire lo stato. Utilizzare le classi quando la funzione statale richiede più metodi.
class Counter
def__init__(self):
self.rely =0
def increment(self):
self.rely =1
return self.rely
# Create a counter occasion
counter1 = Counter()
print(counter1.increment()) #Output:1
print(counter1.increment()) #Output:2
print(counter1.increment()) #Output:3
# Create one other counter occasion
counter2 = Counter()
print(counter2.increment()) #Output:1
print(counter2.increment()) #Output:2
Quando non usare le lezioni
Script semplici e piccoli programmi
Per piccoli script e programmi semplici, l’uso di funzioni senza classi può mantenere il codice semplice e facile da capire.
Funzioni apolide
Se le tue funzioni non devono mantenere uno stato e eseguire solo operazioni in base agli argomenti di enter, l’utilizzo di funzioni semplici è spesso più appropriato.
Finest follow per l’utilizzo delle lezioni
Convenzioni di denominazione
- Utilizzo
CamelCase
per i nomi delle classi. - Usa nomi descrittivi che trasmettono lo scopo della classe.
Principio di responsabilità singola
Assicurarsi che ogni classe abbia una sola responsabilità o scopo. Questo li rende più facili da capire e mantenere.
Le migliori pratiche per le funzioni di scrittura
Lunghezza e complessità della funzione
- Le funzioni dovrebbero essere piccole, con l’attenzione su un singolo oggetto.
- Obiettivo perché le funzioni non siano più lunghe di 50 righe; Se sono più lunghi, considera il refactoring.
Funzioni pure
Scrivere funzioni pure ove possibile. La sua uscita è determinata solo dal suo enter e non ha effetti collaterali. Produce sempre lo stesso output per lo stesso enter. Ha diversi vantaggi, tra cui take a look at e debug più facili, nonché una migliore manutenibilità e riusabilità del codice.
Facilitano anche la programmazione parallela e simultanea poiché non si basano sullo stato condiviso o sui dati mutabili.
def add(a,b):
"""Add two numbers."""
return a + b
#Utilization
end result = add(4,2)
print(end result) # Output:6
Funzioni impure
Si basa sullo stato esterno e produce effetti collaterali, il che rende imprevedibile il suo comportamento.
complete = 0
def add_to_total(worth):
"""Add a worth to the worldwide complete"""
international complete
complete += worth
#Utilization:
add_to_total(4)
print(complete) #Output: 4
add_to_total(2)
print(complete) #Output: 6
Documentazione
- Usa i documenti per documentare lo scopo e il comportamento delle funzioni
- Includi suggerimenti di tipo per specificare i tipi di enter e output previsti
Metodi statici
Viene usato quando si desidera che un metodo sia associato a una classe piuttosto che a un’istanza della classe. Di seguito sono riportati alcuni scenari.
- Raggruppando le funzioni di utilità. È un gruppo di funzioni correlate che appartengono logicamente a una classe ma non dipendono da attributi o metodi di istanza.
- Organizzazione del codice. Aiuta a organizzare il codice raggruppando le funzioni correlate con in una classe, anche se non operano su dati a livello di istanza.
- Incapsulamento. Comunica chiaramente di essere correlati alla classe, non a nessuna istanza specifica, il che può migliorare la leggibilità del codice.
Dateutils.py
from datetime import datetime
class Dateutils:
@staticmethod
def is_valid_date(date_str, format="%Y-%m-%d"):
"""
checks if a string is a legitimate date within the specified format.
Args:
date_str(Str): the date strig to validate.
format(str, optionally available): the date format to make use of (default "%Y-%m-%d").
Returns:
bool: true if the date is legitimate, false in any other case.
"""
attempt:
datetime.strptime(date_str, format)
return True
besides ValueError:
return False
@staticmethod
def get_days_difference(date1_str, date2_str, format ="%Y-%m-%d"):
"""
calculates variety of days between two dates
Args:
date1_str(Str): the primary date string.
date2_str(Str): the second date string.
format(str, optionally available): the date format to make use of (default "%Y-%m-%d").
Returns:
int: the variety of days between two dates.
"""
date1 = datetime.strptime(date1_str, format)
date2 = datetime.strptime(date2_str, format)
return abs(date2 - date1).days) # abs() is used for non adverse distinction
#utilization
valid_date = DateUtils.is_valid_date("2025-03-07")
print(f"Is'2025-03-07' is a legitimate date? {valid_date}") #output:True
days_diff = DateUtils.get_days_difference("2025-02-01","2025-03-01")
print(f"Days between '2025-02-26' and '2025-03-01': {days_diff}"
LOgger
È un modulo di registrazione integrato che è un sistema flessibile e potente per la gestione dei registri delle applicazioni. È essenziale per diagnosticare problemi e monitorare il comportamento dell’applicazione.
IL RotatingFileHandler
è uno strumento potente per la gestione dei file di registro. Ti consente di creare file di registro che ruotano automaticamente quando raggiungono una certa dimensione.
log_base_config.py
import logging
from logging.handlers import RotatingFileHandler
def setup_logging():
#create logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)
#create a rotating file handler
rotating_handler = RotatingFileHandler('instance.log', maxBytes=1024, backupcount =30)
rotating_handler.setLevel(logging.INFO)
#create a formatter and add it to the handler
formatter = logging.Formatter('%(asctime)s - %(identify)s - %(levelname)s - %(message)s')
rotating_handler.setFormatter(formatter)
#add rotating file handler to the logger
logger.addHandler(rotating_handler)
logger_impl.py
import logging
from log_base_config import setup_loggimg
setup_logging()
logger = logging.getLogger("logger_example")
def call_logger(numerator:int,denominator:int):
logger.information("call_logger(): begin")
#log some messages
for i in vary(32):
logger.information(f'This can be a message {i}')
attempt:
end result = numerator / denominator
logger.information("Division profitable: %d / %d = %f", numerator, denominator, end result)
return end result
besides ZeroDivisionError:
logger.error("Did not carry out division attributable to a zero division error.")
return None
logger.information("call_logger(): finish")
if __name__ == "__main__":
call_logger(12,0)
Non consumare l’eccezione
Sta catturando un’eccezione senza intraprendere azioni applicable come la registrazione dell’errore o la sollevamento di nuovo. Questo può rendere difficile il debug perché il programma fallisce silenziosamente. Invece è necessario gestire l’eccezione in modo da fornire informazioni utili e consentire all’applicazione di recuperare o fallire con grazia.
Ecco come puoi gestire correttamente le eccezioni senza consumarle:
- Assicurarsi che i dettagli dell’eccezione siano registrati.
- Fornire suggestions intuitivi o intraprendere azioni correttive.
- Se appropriato, solleva nuovamente l’eccezione dopo averlo registrato.
Di seguito è riportato un esempio che mostra come gestire e registrare correttamente a ZeroDivisionError
senza consumare l’eccezione.
import logging
from log_base_config import setup_loggimg
setup_logging()
logger = logging.getLogger("logger_example")
def divide_numbers(numerator, denominator):
attempt:
end result = numerator / denominator
logger.information("Division profitable: %d / %d = %f", numerator, denominator, end result)
return end result
besides ZeroDivisionError as e:
logger.error("Division by zero error: %d / %d", numerator, denominator)
logger.exception("Exception particulars:")
#elevate the exception once more after logging
elevate
# take a look at the perform
num = 10
denon = 0
attempt
logger.information("Trying to divide %d by %d", num, denom)
end result = divide_number(num, denom)
besides ZeroDivisionError:
logger.error("Did not carry out division attributable to a zero division error.")
Conclusione
Seguendo queste tecniche, si può garantire che le eccezioni siano gestite in modo trasparente, aiutando a debug e mantenendo un solido comportamento delle applicazioni.