logo

Python の定数の型 | Python における定数の重要性

このチュートリアルでは、定数の型と、それらがコードの可読性の向上にどのように役立つかについて学びます。よく知らない方のために説明すると、定数はプログラムの実行中に変化しない値を表す名前です。これらは、プログラミングにおける最も一般的な基本概念です。ただし、Python には定数を定義するための専用の構文がありません。一般に、Python 定数は決して変更されない変数です。次のセクションでは、Python 定数について詳しく説明します。

定数とは何ですか?

一般に、定数項は数学で使用され、決して変化しない値または量です。プログラミングにおいて、定数とは、プログラミングの実行中に決して変更されない値に関連付けられた名前を指します。プログラミング定数は他の定数とは異なり、名前とそれに関連付けられた値の 2 つで構成されます。名前は定数の内容を説明し、値は定数自体の具体的な表現です。

定数を定義すると、その値にアクセスすることのみが可能になりますが、時間の経過とともに変更することはできません。ただし、変数の値は変更できます。実際の例としては、光の速度、1 時間の分数、プロジェクトのルート フォルダーの名前などがあります。

定数を使用する理由

プログラミング言語では、定数を使用すると、デバッグが難しいエラーを引き起こす可能性がある誤って値を変更することを防ぐことができます。コードを読みやすく、保守しやすくすることも役立ちます。定数の利点をいくつか見てみましょう。

    可読性の向上 -コードの可読性を向上させるのに役立ちます。たとえば、実際の速度値そのものよりも、MAX_SPEED という名前の定数の方が読みやすく理解しやすいです。意図を明確に伝える -ほとんどの開発者は 3.14 を pi 定数と考えています。ただし、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 名は厳密な定数であることに注意してください。つまり、それらを再割り当てすることはできず、再割り当てしようとすると構文エラーが発生します。これら 2 つの値は Python ではシングルトン オブジェクトであり、インスタンスが 1 つだけ存在することを意味します。

内部ダンダー名

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

上記のコードでは、 数学.pi カスタムの代わりに PI 定数。数学関連の定数は、より多くのコンテキストをプログラムに提供します。 math.pi 定数を使用する利点は、古いバージョンの Python を使用している場合に、32 ビット バージョンの Pi を取得できることです。上記のプログラムを最新バージョンの Python で使用すると、64 ビット バージョンの pi が得られます。したがって、プログラムは具体的な実行環境に自己適応します。

string モジュールは、いくつかの便利な組み込み文字列定数も提供します。以下は、各定数の名前と値の表です。

名前 価値
ascii_小文字 Abcdefghijklmnopqrstuvwxyz
ascii_大文字 ABCDEFGHIJKLMNOPQRSTUVWXYZ
ascii_letters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
数字 0123456789
16 進数 0123456789abcdefABCDEF
8 桁の数字 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) 

宣言された名前が再割り当てされた場合にエラーを報告するために、型エラーを示す定数変数を Final クラスに指定しました。ただし、型チェッカーのエラーのレポートは取得されます。 Python は MAX_SPEED の値を変更します。したがって、Final は実行時に頻繁に起こる偶発的な再代入を防ぐことはできません。

文字列定数

前のセクションで説明したように、Python は厳密な定数をサポートしていません。決して変化しない変数があるだけです。したがって、Python コミュニティでは、定数変数を識別するために大文字を使用するという命名規則に従っています。

さまざまなレベルの多くのプログラマーがいる大規模な Python プロジェクトに取り組んでいる場合、問題になる可能性があります。したがって、厳密な定数を使用できるメカニズムを用意することをお勧めします。ご存知のとおり、Python は動的言語であり、定数を変更不可能にする方法がいくつかあります。このセクションでは、これらの方法のいくつかについて学びます。

.__slots__ 属性

Python クラスは、__slots__ 属性を使用する機能を提供します。スロットには、オブジェクトのサイズを縮小するための特別なメカニズムが備わっています。これは、オブジェクトのメモリ最適化の概念です。クラスで __slots__ 属性を使用する場合、__dict__ 属性が使用されないため、新しいインスタンスを追加できません。さらに、 .__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 デコレータ

私たちも使うことができます @財産 デコレータを使用して、定数の名前空間として機能するクラスを作成します。 setter メソッドを提供せずに constants プロパティを定義するだけで済みます。次の例を理解してみましょう。

例 -

 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 

これらは単なる読み取り専用のプロパティです。再割り当てしようとすると、 属性エラー。

namedtuple() ファクトリ関数

Python のコレクション モジュールには、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 に使用してデータ クラスにしました。データ クラスを不変にするために、frozen 引数を 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__() メソッドでは、クラスの属性に対して代入操作を実行できません。再割り当てしようとすると、単に 属性エラー。

結論

定数は、プログラミングの概念、特に数学用語で最もよく使用されます。このチュートリアルでは、定数とそのフレーバーの重要な概念について学びました。 Python コミュニティでは、定数を識別するための名前規則として大文字を使用します。ただし、Python で定数を使用するためのいくつかの高度な方法について説明しました。定数を使用してコードの可読性、再利用性、保守性を向上させる方法について説明しました。 Python 定数を厳密に一定にするためにさまざまなテクニックを適用する方法について説明しました。