logo

Типи констант у Python | Важливість константи в Python

У цьому підручнику ми дізнаємося про типи констант і те, як вони допомагають покращити читабельність коду. Якщо ви не знайомі, константи - це імена, що представляють значення, які не змінюються під час виконання програми. Вони є найпоширенішою фундаментальною концепцією програмування. Однак Python не має спеціального синтаксису для визначення констант. Загалом константи Python є змінними, які ніколи не змінюються. Ми детально обговоримо константу Python у наступному розділі.

Що таке константи?

Як правило, у математиці використовується постійний термін, значення або величина, яка ніколи не змінюється. У програмуванні константа відноситься до імені, пов’язаного зі значенням, яке ніколи не змінюється під час виконання програмування. Програмна константа відрізняється від інших констант і складається з двох речей – імені та пов’язаного значення. Ім’я опише суть константи, а значення є конкретним виразом самої константи.

Визначивши константу, ми можемо лише отримати доступ до її значення, але не можемо змінити її з часом. Однак ми можемо змінити значення змінної. Приклад із реального життя: швидкість світла, кількість хвилин у годині та назва кореневої папки проекту.

Навіщо використовувати Constant?

У мовах програмування константи дозволяють нам захистити від випадкової зміни їх значення, що може спричинити помилки, які важко налагодити. Це також корисно зробити код більш читабельним і зручним для обслуговування. Давайте розглянемо деякі переваги константи.

    Покращена читаність -Це допомагає покращити читабельність коду. Наприклад, легше прочитати та зрозуміти константу з іменем MAX_SPEED, ніж саме значення істотної швидкості.Чітке повідомлення про наміри -Більшість розробників вважають 3.14 постійною пі. Однак назва Pi, pi або PI чіткіше передасть намір. Ця практика дозволить іншому розробнику зрозуміти наш код.Краща ремонтопридатність -Константи дозволяють нам використовувати одне й те саме значення у вашому коді. Припустимо, ми хочемо оновити значення константи; нам не потрібно змінювати кожен екземпляр.Низький ризик помилок -Константа, що представляє задане значення в програмі, менш схильна до помилок. Якщо ми хочемо змінити точність обчислень, заміна значення може бути ризикованою. Замість того, щоб замінювати його, ми можемо створити різні константи для різних рівнів точності та змінити код там, де нам потрібно.Потоково-безпечне зберігання даних -Константи є потокобезпечними об’єктами, тобто кілька потоків можуть одночасно використовувати константу без ризику втрати даних.

Визначені користувачем константи

Щоб визначити константу в Python, нам потрібно використовувати угоду про іменування в Python. Ім'я потрібно писати великими літерами, розділяючи слова підкресленням.

Нижче наведено приклад визначених користувачем констант Python -

 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', ... ] 

Ми використовували той самий спосіб, що й для створення змінних у Python. Таким чином, ми можемо припустити, що константи Python є просто змінними, і єдина відмінність полягає в тому, що константа використовує лише великі літери.

Використання великих літер виділяє константу серед наших змінних і є корисною або бажаною практикою.

Вище ми обговорили користувачів, визначених користувачем; Python також надає кілька внутрішніх імен, які можна розглядати як константи.

Важливі константи в Python

У цьому розділі ми дізнаємося про деякі внутрішні константи, які використовуються, щоб зробити код Python більш читабельним. Давайте розберемося з деякими важливими константами.

Вбудовані константи

В офіційній документації Правда і помилковий вказані як перша константа. Це логічні значення Python і є екземпляром int. А Правда має значення 1, і помилковий має значення 0.

приклад -

 >>> 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 

Пам'ятайте, що імена True і False є суворими константами. Іншими словами, ми не можемо їх перепризначити, і якщо ми спробуємо їх перепризначити, ми отримаємо синтаксичну помилку. Ці два значення є одиночними об’єктами в Python, тобто існує лише один екземпляр.

Внутрішні імена Dunder

Python також має багато внутрішніх грім імена, які ми можемо вважати константами. Є кілька таких унікальних імен, ми дізнаємося про __name__ і __file__ у цьому розділі.

Атрибут __name__ пов’язаний із тим, як запускати певний фрагмент коду. Під час імпорту модуля внутрішні Python встановлюють __name__ на рядок, що містить назву модуля.

новий_файл.py

 print(f'The type of __name__ is: {type(__name__)}') print(f'The value of __name__ is: {__name__}') 

У командному рядку введіть таку команду -

 python -c 'import new_file' 

Параметр -c використовується для виконання невеликого фрагмента коду Python у командному рядку. У наведеному вище прикладі ми імпортували новий_файл модуль, який виводить деякі повідомлення на екран.

вихід -

 The type of __name__ is: The value of __name__ is: timezone 

Як ми бачимо, __name__ зберігає рядок __main__, що вказує на те, що ми можемо запускати виконувані файли безпосередньо як програму Python.

З іншого боку, атрибут __file__ містить файл, який Python зараз імпортує або виконує. Якщо ми використовуємо атрибут __file__ всередині файлу, ми отримаємо шлях до самого модуля.

Давайте розглянемо наступний приклад -

приклад -

 print(f'The type of __file__ is: {type(__file__)}') print(f'The value of __file__ is: {__file__}') 

Вихід:

 The type of __file__ is: The value of __file__ is: D:Python Project
ew_file.py 

Ми також можемо запустити безпосередньо і отримаємо той самий результат.

приклад -

 print(f'The type of __file__ is: {type(__file__)}') print(f'The value of __file__ is: {__file__}') 

Вихід:

 python new_file.py The type of __file__ is: The value of __file__ is: timezone.py 

Корисні рядкові та математичні константи

У стандартній бібліотеці є багато цінних констант. Деякі з них суворо пов’язані з конкретними модулями, функціями та класами; багато з них є загальними, і ми можемо використовувати їх у кількох сценаріях. У наведеному нижче прикладі ми будемо використовувати математичні та рядкові модулі math і string відповідно.

Давайте розберемо такий приклад -

приклад -

список java в масив
 >>> 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 

Ці константи відіграватимуть важливу роль, коли ми пишемо математичний код або виконуємо певні обчислення.

Давайте розберемо такий приклад -

приклад -

 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})' 

У наведеному вище коді ми використали math.pi замість звичаю PI константи. Математична константа надає програмі більше контекстів. Перевага використання константи math.pi полягає в тому, що якщо ми використовуємо старішу версію Python, ми отримаємо 32-розрядну версію Pi. Якщо використовувати наведену вище програму в сучасній версії Python, ми отримаємо 64-розрядну версію pi. Таким чином, наша програма буде самостійно адаптуватися до свого конкретного середовища виконання.

Модуль string також надає деякі корисні вбудовані константи рядків. Нижче наведено таблицю імен і значень кожної константи.

Ім'я Значення
ascii_нижній регістр А Б В Г Г Д Е Є Ж З И І Ї Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ ью я
ascii_uppercase А Б В Г Г Д Е Є Ж З И І Ї Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ ЬЮ Я
ascii_letters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
цифри 0123456789
шістнадцяткові цифри 0123456789abcdefABCDEF
вісім цифр 01234567

Ми можемо використовувати ці пов’язані з рядками константи в регулярних виразах, обробці природної мови, з великою кількістю обробки рядків тощо.

Константи для анотації типу

Починаючи з Python 3.8, модуль введення містить клас Final, який дозволяє нам коментувати константи. Якщо ми використовуємо клас Final для визначення констант у програмі, ми отримаємо статичну помилку типу, яку перевіряє засіб перевірки mypy, і він покаже, що ми не можемо перепризначити назву Final. Давайте розберемося в наступному прикладі.

приклад -

 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) 

Ми вказали постійну змінну з кінцевим класом, який вказує на помилку типу, щоб повідомити про помилку, якщо оголошене ім’я перепризначається. Однак він отримує звіт про помилку перевірки типу; Python змінює значення MAX_SPEED. Отже, Final не запобігає постійному випадковому перепризначенню під час виконання.

Рядкові константи

Як обговорювалося в попередньому розділі, Python не підтримує строгі константи; він просто має змінні, які ніколи не змінюються. Таким чином, спільнота Python дотримується угоди про використання імен великих літер для ідентифікації постійних змінних.

Це може бути проблемою, якщо ми працюємо над великим проектом Python з багатьма програмістами на різних рівнях. Тому було б гарною практикою мати механізм, який дозволяє нам використовувати строгі константи. Як ми знаємо, Python є динамічною мовою, і є кілька способів зробити константи незмінними. У цьому розділі ми дізнаємося про деякі з цих способів.

Атрибути .__slots__

Класи Python надають можливість використовувати атрибути __slots__. Слот має спеціальний механізм для зменшення розміру об'єктів. Це концепція оптимізації пам'яті об'єктів. Якщо ми використовуємо атрибут __slots__ у класі, ми не зможемо додати новий екземпляр, оскільки він не використовує атрибути __dict__. Крім того, не маючи a .__dict__ атрибут передбачає оптимізацію з точки зору споживання пам'яті. Давайте розберемося в наступному прикладі.

Приклад – без використання атрибутів __slots__

 class NewClass(object): def __init__(self, *args, **kwargs): self.a = 1 self.b = 2 if __name__ == '__main__': instance = NewClass() print(instance.__dict__) 

вихід -

 {'a': 1, 'b': 2} 

Кожен об’єкт у Python містить динамічний словник, який дозволяє додавати атрибути. Словники споживають багато пам’яті, а використання __slots__ зменшує втрату місця та пам’яті. Давайте подивимося інший приклад.

приклад -

 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) 

вихід -

 3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 10, in AttributeError: 'ConstantsName' object attribute 'PI' is read-only 

У наведеному вище коді ми ініціалізували атрибути класу атрибутами слотів. Змінна має постійне значення, якщо ми спробуємо перепризначити змінну, ми отримаємо помилку.

Декоратор @property

Ми також можемо використовувати @власність декоратор для створення класу, який працює як простір імен для констант. Нам просто потрібно визначити властивість констант, не надаючи їм метод встановлення. Давайте розберемося в наступному прикладі.

приклад -

 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) 

вихід -

 3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 13, in AttributeError: can't set attribute 

Це властивості лише для читання, якщо ми спробуємо перепризначити, ми отримаємо AttributeError.

Фабрична функція namedtuple().

Модуль колекції Python постачається з фабричною функцією namedtuple(). Використовуючи namedtuple() ми можемо використовувати іменовані поля та крапкову нотацію для доступу до їхніх елементів. Ми знаємо, що кортежі є незмінними, а це означає, що ми не можемо змінити існуючий іменований об’єкт кортежу на місці.

Давайте розберемося в наступному прикладі.

приклад -

 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) 

вихід -

 3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 17, in AttributeError: can't set attribute 

Декоратор @dataclass

Як випливає з назви, клас даних містить дані, вони можуть складатися з методів, але це не є їх основною метою. Нам потрібно використовувати декоратор @dataclass для створення класів даних. Ми також можемо створити строгі константи. Декоратор @dataclass приймає заморожений аргумент, який дозволяє нам позначити наш клас даних як незмінний. Переваги використання декоратора @dataclass: ми не можемо змінювати його атрибут екземпляра.

Давайте розберемося в наступному прикладі.

приклад -

 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) 

вихід -

 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' 

Пояснення -

У наведеному вище коді ми імпортували декоратор @dataclass. Ми використали цей декоратор для ConstantsName, щоб зробити його класом даних. Ми встановлюємо для замороженого аргументу значення True, щоб зробити клас даних незмінним. Ми створили екземпляр класу даних і маємо доступ до всіх констант, але не можемо їх змінювати.

Спеціальний метод .__setattr__().

Python дозволяє нам використовувати спеціальний метод під назвою .__setattr__(). Використовуючи цей метод, ми можемо налаштувати процес призначення атрибутів, оскільки Python автоматично викликає метод під час кожного призначення атрибутів. Давайте розберемо такий приклад -

приклад -

 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) 

вихід -

 3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 22, in File '', line 17, in __setattr__ AttributeError: can't reassign constant 'PI' 

Метод __setattr__() не дозволяє виконувати жодну операцію присвоєння атрибутам класу. Якщо ми спробуємо перепризначити, це просто підніме AttributeError.

Висновок

Константи найчастіше використовуються в концепції програмування, особливо в математичному терміні. У цьому підручнику ми дізналися про важливі поняття констант і їх смаків. Спільнота Python використовує великі літери як угоду про імена для ідентифікації констант. Однак ми обговорили деякі попередні способи використання констант у Python. Ми обговорили, як покращити читабельність коду, можливість повторного використання та обслуговування за допомогою констант. Ми згадали, як застосувати різні техніки, щоб зробити наші константи Python строго постійними.