In questo tutorial impareremo a conoscere i tipi costanti e come aiutano a migliorare la leggibilità del codice. Se non hai familiarità, le costanti sono i nomi che rappresentano i valori che non cambiano durante l'esecuzione del programma. Sono il concetto fondamentale più comune nella programmazione. Tuttavia, Python non ha una sintassi dedicata per definire le costanti. In generale, le costanti Python sono variabili che non cambiano mai. Avremo una discussione dettagliata sulla costante Python nella prossima sezione.
Cosa sono le costanti?
Generalmente in matematica si usa un termine costante, un valore o una quantità che non cambia mai. Nella programmazione, una costante si riferisce al nome associato ad un valore che non cambia mai durante l'esecuzione della programmazione. La costante di programmazione è diversa dalle altre costanti e consiste di due cose: un nome e un valore associato. Il nome descriverà il significato della costante e il valore è l'espressione concreta della costante stessa.
Una volta definita la costante, possiamo solo accedere al suo valore ma non possiamo modificarlo nel tempo. Possiamo però modificare il valore della variabile. Un esempio reale è: la velocità della luce, il numero di minuti in un'ora e il nome della cartella principale di un progetto.
Perché usare Costante?
Nei linguaggi di programmazione, le costanti ci consentono di proteggerci dalla modifica accidentale del loro valore che può causare errori difficili da eseguire il debug. È anche utile rendere il codice più leggibile e gestibile. Vediamo alcuni vantaggi della costante.
Costanti definite dall'utente
Dobbiamo usare la convenzione di denominazione in Python per definire la costante in Python. Dovremmo scrivere il nome in maiuscolo con un trattino basso a separare le parole.
Di seguito sono riportati gli esempi delle costanti Python definite dall'utente:
PI = 3.14 MAX_SPEED = 300 DEFAULT_COLOR = ' 33[1;34m' WIDTH = 20 API_TOKEN = '567496396372' BASE_URL = 'https://api.example.com' DEFAULT_TIMEOUT = 5 BUILTINS_METHODS = ('sum', 'max', 'min', 'abs') INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', ... ]
Abbiamo usato lo stesso modo in cui creiamo le variabili in Python. Quindi possiamo supporre che le costanti Python siano solo variabili e l'unica distinzione è che la costante utilizza solo lettere maiuscole.
L'uso delle lettere maiuscole fa risaltare la costante rispetto alle nostre variabili ed è una pratica utile o preferita.
Sopra abbiamo discusso degli utenti definiti dall'utente; Python fornisce anche diversi nomi interni che possono essere considerati e dovrebbero essere trattati come costanti.
Costanti importanti in Python
In questa sezione impareremo alcune costanti interne che vengono utilizzate per rendere il codice Python più leggibile. Comprendiamo alcune costanti importanti.
Costanti integrate
Nella documentazione ufficiale, il VERO E Falso sono elencati come la prima costante. Questi sono valori booleani Python e sono l'istanza dell'int. UN VERO ha un valore di 1, e Falso ha un valore 0.
Esempio -
>>> True True >>> False False >>> isinstance(True, int) True >>> isinstance(False, int) True >>> int(True) 1 >>> int(False) 0 >>> True = 42 ... SyntaxError: cannot assign to True >>> True is True True >>> False is False True
Ricorda che i nomi Vero e Falso sono costanti rigorose. In altre parole, non possiamo riassegnarli e se proviamo a riassegnarli otterremo un errore di sintassi. Questi due valori sono oggetti singleton in Python, il che significa che esiste solo un'istanza.
Nomi Dunder interni
Python ne ha anche molti interni tuono nomi che possiamo considerare costanti. Esistono molti di questi nomi univoci, impareremo a conoscere __name__ e __file__ in questa sezione.
L'attributo __name__ è correlato a come eseguire un determinato pezzo di codice. Quando si importa un modulo, Python imposta internamente __name__ su una stringa contenente il nome del modulo.
nuovo_file.py
print(f'The type of __name__ is: {type(__name__)}') print(f'The value of __name__ is: {__name__}')
Nella riga di comando digitare il seguente comando:
python -c 'import new_file'
Il -c viene utilizzato per eseguire un piccolo pezzo di codice Python dalla riga di comando. Nell'esempio sopra, abbiamo importato il file nuovo file modulo, che visualizza alcuni messaggi sullo schermo.
Produzione -
The type of __name__ is: The value of __name__ is: timezone
Come possiamo vedere, __name__ memorizza la stringa __main__, indica che possiamo eseguire i file eseguibili direttamente come programma Python.
D'altra parte, l'attributo __file__ ha il file che Python sta attualmente importando o eseguendo. Se utilizziamo l'attributo __file__ all'interno del file, otterremo il percorso del modulo stesso.
Vediamo il seguente esempio -
Esempio -
print(f'The type of __file__ is: {type(__file__)}') print(f'The value of __file__ is: {__file__}')
Produzione:
The type of __file__ is: The value of __file__ is: D:Python Project ew_file.py
Possiamo anche correre direttamente e otterremo lo stesso risultato.
Esempio -
print(f'The type of __file__ is: {type(__file__)}') print(f'The value of __file__ is: {__file__}')
Produzione:
python new_file.py The type of __file__ is: The value of __file__ is: timezone.py
Stringhe e costanti matematiche utili
Ci sono molte costanti preziose nella libreria standard. Alcuni sono strettamente collegati a moduli, funzioni e classi specifiche; molti sono generici e possiamo usarli in diversi scenari. Nell'esempio seguente utilizzeremo rispettivamente i moduli math e string relativi alle stringhe.
Comprendiamo il seguente esempio:
Esempio -
>>> import math >>> math.pi 3.141592653589793 >>> math.tau 6.283185307179586 >>> math.nan nan >>> math.inf inf >>> math.sin(30) -0.9880316240928618 >>> math.cos(60) -0.9524129804151563 >>> math.pi 3.141592653589793
Queste costanti giocheranno un ruolo fondamentale quando scriviamo codice relativo alla matematica o eseguiamo calcoli specifici.
Comprendiamo il seguente esempio:
Esempio -
import math class Sphere: def __init__(self, radius): self.radius = radius def area(self): return math.pi * self.radius**2 def perimeter(self): return 2 * math.pi * self.radius def projected_volume(self): return 4/3 * math.pi * self.radius**3 def __repr__(self): return f'{self.__class__.__name__}(radius={self.radius})'
Nel codice sopra abbiamo utilizzato il file matematica.pi invece che personalizzato PI costanti. La costante relativa alla matematica fornisce più contesti al programma. Il vantaggio di utilizzare la costante math.pi è che se utilizziamo una versione precedente di Python, otterremo una versione di Pi a 32 bit. Se utilizziamo il programma sopra nella versione moderna di Python, otterremo una versione di pi a 64 bit. Quindi il nostro programma si adatterà automaticamente al suo ambiente di esecuzione concreto.
Il modulo string fornisce anche alcune utili costanti stringa integrate. Di seguito è riportata la tabella del nome e del valore di ciascuna costante.
Nome | Valore |
---|---|
ascii_lowercase | Abcdefghijklmnopqrstuvwxyz |
ascii_maiuscolo | ABCDEFGHIJKLMNOPQRSTUVWXYZ |
ascii_letters | ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz |
cifre | 0123456789 |
cifre esadecimali | 0123456789abcdefABCDEF |
ottdigits | 01234567 |
Possiamo utilizzare queste costanti relative alle stringhe nelle espressioni regolari, nell'elaborazione del linguaggio naturale, nell'elaborazione delle stringhe e altro ancora.
Costanti di annotazione del tipo
A partire da Python 3.8, il modulo di digitazione include una classe Final che ci consente di digitare e annotare le costanti. Se utilizziamo la classe Final per definire le costanti nel programma, otterremo l'errore di tipo statico che il mypy checker controlla e mostrerà che non possiamo riassegnare al nome Final. Comprendiamo il seguente esempio.
f film
Esempio -
from typing import Final MAX_Marks: Final[int] = 300 MAX_Students: Final[int] = 500 MAX_Marks = 450 # Cannot assign to final name 'MAX_SPEED' mypy(error)
Abbiamo specificato la variabile costante con la Classe Finale che indicava l'errore di tipo per segnalare un errore se un nome dichiarato viene riassegnato. Tuttavia, riceve un rapporto sull'errore del controllo del tipo; Python modifica il valore di MAX_SPEED. Pertanto, Final non impedisce la costante riassegnazione accidentale in fase di esecuzione.
Costanti di stringa
Come discusso nella sezione precedente, Python non supporta costanti rigide; ha semplicemente variabili che non cambiano mai. Pertanto, la comunità Python segue la convenzione di denominazione che prevede l'utilizzo della lettera maiuscola per identificare le variabili costanti.
Può essere un problema se lavoriamo su un grande progetto Python con molti programmatori a diversi livelli. Quindi sarebbe una buona pratica avere un meccanismo che ci permetta di usare costanti rigorose. Come sappiamo, Python è un linguaggio dinamico ed esistono diversi modi per rendere immutabili le costanti. In questa sezione impareremo alcuni di questi modi.
Gli attributi .__slots__
Le classi Python forniscono la possibilità di utilizzare gli attributi __slots__. La fessura ha lo speciale meccanismo per ridurre le dimensioni degli oggetti. È un concetto di ottimizzazione della memoria sugli oggetti. Se utilizziamo l'attributo __slots__ nella classe, non saremo in grado di aggiungere la nuova istanza, perché non utilizza gli attributi __dict__. Inoltre, non avere a .__detto__ L'attributo implica un'ottimizzazione in termini di consumo di memoria. Comprendiamo il seguente esempio.
Esempio: senza utilizzare gli attributi __slots__
class NewClass(object): def __init__(self, *args, **kwargs): self.a = 1 self.b = 2 if __name__ == '__main__': instance = NewClass() print(instance.__dict__)
Produzione -
{'a': 1, 'b': 2}
Ogni oggetto in Python contiene un dizionario dinamico che consente di aggiungere attributi. I dizionari consumano molta memoria e l'utilizzo di __slots__ riduce lo spreco di spazio e memoria. Vediamo un altro esempio.
Esempio -
class ConstantsName: __slots__ = () PI = 3.141592653589793 EULER_NUMBER = 2.718281828459045 constant = ConstantsName() print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
Produzione -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 10, in AttributeError: 'ConstantsName' object attribute 'PI' is read-only
Nel codice precedente, abbiamo inizializzato gli attributi della classe con gli attributi degli slot. La variabile ha un valore costante, se proviamo a riassegnare la variabile, otterremo un errore.
Il decoratore @property
Possiamo anche usare @proprietà decoratore per creare una classe che funzioni come spazio dei nomi per le costanti. Dobbiamo solo definire la proprietà delle costanti senza fornire loro un metodo setter. Comprendiamo il seguente esempio.
Esempio -
class ConstantsName: @property def PI(self): return 3.141592653589793 @property def EULER_NUMBER(self): return 2.718281828459045 constant = ConstantsName() print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
Produzione -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 13, in AttributeError: can't set attribute
Sono solo proprietà di sola lettura, se proviamo a riassegnarle, otterremo un file Errore attributo.
La funzione di fabbrica nametuple()
Il modulo di raccolta di Python viene fornito con la funzione di fabbrica chiamata nametuple(). Usando il nometupla() funzione, possiamo utilizzare i campi con nome e la notazione punto per accedere ai loro elementi. Sappiamo che le tuple sono immutabili, il che significa che non possiamo modificare sul posto un oggetto tupla con nome esistente.
Comprendiamo il seguente esempio.
Esempio -
from collections import namedtuple ConstantsName = namedtuple( 'ConstantsName', ['PI', 'EULER_NUMBER'] ) constant = ConstantsName(3.141592653589793, 2.718281828459045) print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
Produzione -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 17, in AttributeError: can't set attribute
Il decoratore @dataclass
Come suggerisce il nome, la classe dati contiene dati, possono essere costituiti da metodi, ma non è il loro obiettivo principale. Dobbiamo utilizzare il decoratore @dataclass per creare le classi di dati. Possiamo anche creare le costanti strict. Il decoratore @dataclass accetta un argomento congelato che ci consente di contrassegnare la nostra classe di dati come immutabile. I vantaggi dell'utilizzo del decoratore @dataclass sono che non possiamo modificare il suo attributo di istanza.
Comprendiamo il seguente esempio.
Esempio -
from dataclasses import dataclass @dataclass(frozen=True) class ConstantsName: PI = 3.141592653589793 EULER_NUMBER = 2.718281828459045 constant = ConstantsName() print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
Produzione -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 19, in File '', line 4, in __setattr__ dataclasses.FrozenInstanceError: cannot assign to field 'PI'
Spiegazione -
Nel codice sopra abbiamo importato il decoratore @dataclass. Abbiamo utilizzato questo decoratore per ConstantsName per renderlo una classe di dati. Impostiamo l'argomento congelato su True per rendere immutabile la classe di dati. Abbiamo creato l'istanza della classe dati e possiamo accedere a tutte le costanti ma non possiamo modificarle.
Il metodo speciale .__setattr__()
Python ci consente di utilizzare un metodo speciale chiamato .__setattr__(). Usando questo metodo, possiamo personalizzare il processo di assegnazione degli attributi perché Python chiama automaticamente il metodo ad ogni assegnazione di attributi. Comprendiamo il seguente esempio:
Esempio -
class ConstantsName: PI = 3.141592653589793 EULER_NUMBER = 2.718281828459045 def __setattr__(self, name, value): raise AttributeError(f'can't reassign constant '{name}'') constant = ConstantsName() print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
Produzione -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 22, in File '', line 17, in __setattr__ AttributeError: can't reassign constant 'PI'
Il metodo __setattr__() non permette di effettuare alcuna operazione di assegnazione sugli attributi della classe. Se proviamo a riassegnare, rilancia semplicemente un Errore attributo.
Conclusione
Le costanti sono più utilizzate concettualmente nella programmazione, soprattutto in termini matematici. In questo tutorial abbiamo appreso i concetti importanti delle costanti e dei suoi sapori. La comunità Python utilizza la lettera maiuscola come convenzione sui nomi per identificare le costanti. Tuttavia, abbiamo discusso alcuni modi avanzati per utilizzare le costanti in Python. Abbiamo discusso come migliorare la leggibilità, la riusabilità e la manutenibilità del codice con le costanti. Abbiamo menzionato come applicare varie tecniche per rendere le nostre costanti Python strettamente costanti.