Skip to content
This page has been auto-translated and may contain errors.View in English

変数と型

docs.scrimba.com

すべてのプログラムは何かを覚えておく必要があります。クイズはプレイヤーの名前が必要です。ゲームは現在のスコアが必要です。天気スクリプトはチェックしている都市が必要です。Pythonはこのために変数を使用します。値に付けた名前で、プログラム全体で使用できます。

変数は値への名前付き参照です。Pythonは=の右側のオブジェクトに名前をバインドし、いつでも再バインドできます。型は名前ではなく値に生きています。

Pythonでは変数は**名前バインディング**です。オブジェクト(Pythonがメモリに保持する任意の値、文字列や数値など)を指す名前であり、値自体を保持するラベル付きボックスではありません。型はオブジェクトに属し、名前には属さないため、1つの名前は1行でstrを指し、次の行でintを指すことができ、エラーは発生しません。この自由度は動的型付けと呼ばれます。名前が指す対象に制限はありません。

python
player_name = "太郎"
score = 0
city = "東京"

3行、Pythonが覚えておく3つのもの。それぞれについて、Pythonはまず右側の値を処理し、左側の名前で格納します。後でその名前を使用すると、Pythonは値を返します。

各行はバインディングを作成します。左側の名前は右側のオブジェクトを参照します。Pythonは右側全体を最初に評価し、次にバインディングを作成します。

各割り当ては現在のスコープ(その名前が見える領域、通常は作業している関数またはファイル)で名前をバインドします。Pythonは常に右辺全体を完全に計算したにバインドするため、正確にはa, b = b, aが1行で2つの値をスワップする理由です。右側が完全に計算されてから、両方の名前が結果を指します。

値の格納

=記号は数学のクラスから来た人をほぼ誰もが混同します。Pythonでは、=は「等しい」を意味しません。それは**この値をこの名前で格納する**ことを意味します:

python
city = "東京"

city"東京"を取得します。Pythonに言っています:"東京"を覚えていて、それにcityというラベルを付けてください。

変数の値をいつでも置き換えることができます。Pythonは最新のものを使用します:

python
score = 0
score = 10   # scoreは今10です
score = 15   # scoreは今15です

=代入です。現在のスコープで名前をオブジェクトにバインドします。変数を更新するための標準的な省略形は**拡張代入**です:

python
score = 0
score += 10   # 同じ意味: score = score + 10
score *= 2    # 同じ意味: score = score * 2

複数の名前を一度にバインドすることもできます:

python
x, y, z = 1, 2, 3
a = b = 0        # 両方ともゼロから開始

代入は名前をオブジェクトに指します。値を新しいコンテナにコピーすることはありません。だから2つの名前は同じオブジェクトを指すことができます:

python
a = "hello"
b = a
print(id(a) == id(b))   # True(両方の名前が1つのオブジェクトを指す)

b = "world"             # bは新しいオブジェクトに再バインド
print(id(a) == id(b))   # False
print(a)                # まだ"hello":bを再バインドはaに影響しません

id()はオブジェクトのアイデンティティを返します。存在している間、そのオブジェクトに一意の番号であり、2つの等しいIDは「文字通り同じオブジェクト」を意味し、等しいことが起こった2つのオブジェクトではありません。ポイントとコピーの違いは今無視するのは魅力的ですが、ミュータブルオブジェクト(その場で変更できるもの、リストなど)で噛みます。2つの名前を1つのリストに指す、どちらかの名前を通じてそれを変更すると、変更は両方に表示されます。リストと辞書はこれを後の章で具体化します。

型アノテーションは、名前が保持することを期待する型を記録します。コードを実行せずに読むツール(型チェッカーとエディタ)のための注記であり、Pythonはプログラムの実行中は無視します:

python
name: str = "太郎"
score: int = 0
ratio: float = 0.85
Juno値の格納=は数学クラスの「等しい」ではなく、「この値をこの名前で隠す」です。いつでも変更できて、Pythonは最新のものを保持します。宣言なし、セットアップなし、あなたがそれに名前を付けて、それが存在します。これを過度に考えるのをやめるのに長すぎました。
Juno値の格納=は名前を値に指し、いつでも再度指すことができます。名前はラベルで、値はものです。それが全体のトリックです。
Juno値の格納=は値をボックスに落とさず、オブジェクトに名前を結びます。再割り当てするだけで名前が移動し、古いオブジェクトはそのままです。リストが現れる前にそれを覚えておくか、2つの名前が静かに1つを共有します。

変数に名前をつける

名前を選択します。Pythonにはいくつかのハードルールがあり、コミュニティは初日から採用する価値のある慣例に従います。明確な名前はコードを数週間後に読みやすくしたいです。謎めいた名前は痛みを引き起こします。

Pythonは識別子構文ルールの小さなセットを強制します。その先は、PEP 8の慣例はすべてのPythonコードベースとツール全体の事実上の標準です。

Pythonが実際に識別子(名前の技術用語)に対して強制するルールは最小限です。残りはPEP 8、Pythonの公式スタイルガイドです。インタプリタ(コードを実行するプログラム)はそれを強制しませんが、リンター(スタイルの問題と可能なバグをフラグするツール)、型チェッカー、すべてのプロフェッショナルコードベースはそれを期待しています。それに対抗することは主に次のコードを読む人に摩擦を生成します。

Pythonが強制するルール:

  • 文字、数字、アンダースコアのみ。スペースやハイフンなし。
  • 文字またはアンダースコアで開始する必要があり、決して数字ではありません
  • 大文字小文字を区別します:scoreScoreSCOREは3つの別個の変数です

誰もが従う慣例(PEP 8):

ものスタイル
変数と関数snake_caseuser_nametotal_price
定数UPPER_SNAKE_CASEMAX_RETRIESBASE_URL
クラスPascalCaseUserAccountDataLoader
python
# 明確な名前、一目瞭然
user_name = "太郎"
total_price = 49.99
is_logged_in = True
MAX_RETRIES = 3

# 1時間以内に後悔するでしょう
x = "太郎"
tp = 49.99
b = True

早期に知る価値のある1つのトラップ:listinputtypeprintなどのPython組み込み後の変数に名前を付けないでください。Pythonはそれを許可しますが、スコープの残りの組み込みを静かに壊し、結果のエラーは追跡しにくいです。

Pythonの組み込みを影で消さないでください。listtypeinputprint、またはstrに割り当てると、警告なしにスコープの残りの組み込みを上書きします。見つけるのが痛い静かなバグです。

UPPER_SNAKE_CASEは慣例であり、強制されません。Pythonは後でMAX_RETRIES = 99を再割り当てするのを止めません。他の開発者への信号にすぎません。

シャドーイング組み込みは、Pythonがすでに提供している(listのような)ものと一致する独自の名前を作成することを意味します。Pythonが名前を検索するとき、ローカル名を独自の組み込みの前にチェックするため、バージョンが優先され、実際のlistはその時点から隠されます。それでもbuiltins.listとして到達可能ですが、通常のコードはもはやそれを見ません。定数については、UPPER_SNAKE_CASEは単なる視覚的信号です;Pythonはそれを喜んで再割り当てさせます。ツールが実際に強制できる定数が必要な場合は、typing.Finalで注釈を付けます。これにより、名前を「再割り当てするためのものではない」とマークするため、型チェッカーはそうした場合にフラグを立てます。

Juno変数に名前をつける 文字、数字、アンダースコア、文字またはアンダースコアで始まります。snake_caseに固執すれば、あなたは黄金です。私の1つのルーキーの間違い:変数をlistまたはprintと呼ばないでください。Pythonはそれを許可し、後で警告なしにすべてが奇妙になります。
Juno変数に名前をつける 名前のsnake_case、定数のUPPER_SNAKE_CASE、すべてのツールがそれを期待しています。そしてlistまたはprintと名前を付けないでください、あなたは組み込みを静かに打ち鳴らします。
Juno変数に名前をつける インタプリタはほぼ名前を強制しませんが、すべてのリンターはそうします。snake_caseと戦うことは単にあなたに悲しみを稼ぐだけです。実際のトラップは`list`のような組み込みをシャドーイングしています。静かに壊れ、そしてあなたがそれをした場所から遠く。

あなたが格納できるもの

Pythonには、ほぼすべてのプログラムで使用する4つの型があります。Pythonは、値の書き方からどの型を意味するかを理解します。明確に型を宣言することはありません。

Pythonはリテラル構文から型を推測します。これら4つの型は基本的な値空間をカバーし、言語内のすべてはそれらの上に構築されます。

Pythonのすべての値は完全なオブジェクトです。42"hi"のようにコードに直接書かれた値であるリテラルさえもです。オブジェクトであることは、値がそれ自身のメソッド(それに取り付けられた関数)を運ぶことを意味するため、"hi".upper()(3).bit_length()はリテラルに直接作用し、最初にラップまたはアンラップするものは何もありません。それについて考える必要はめったにありません、それがポイントです。以下の4つの型は、ほぼすべてのプログラムで到達するものです。

テキスト(str

任意のテキストは引用符(一重または二重)の中に入ります。引用符はPythonに、変数名ではなく文字通りの文字を意味することを伝えます。作成されたら、文字列はその場で変更することはできません。文字列章は、文字列でできることすべてをカバーしています。

python
player_name = "太郎"
city = "東京"
message = 'ゲームオーバー'

テキストに使用符号が含まれている場合は、二重引用符を使用してそれをエスケープする必要がありません:

python
note = "It's a great day"
note = 'It\'s a great day'   # 同じ結果、エスケープを使用して

文字列は単一引用符または二重引用符の任意のテキストを保持します。彼らはイミュータブルです:どの操作も文字列をその場で変更しません。すべての変換は新しいものを返します。これは重要です。ループ内で繰り返される+は各ステップで新しい文字列オブジェクトを作成します。文字列章は効率的な代替手段をカバーしています。

python
player_name = "太郎"
city = "東京"
note = "It's a great day"

strイミュータブルなUnicodeコードポイントのシーケンスです(イミュータブルはそれが作成された後に変更されることはできないことを意味します;コードポイントは文字自体であり、それらが格納される生のバイトではありません)、これがlen("café")が4ではなく5である理由です。文字列は変更できないため、ハッシュ可能であり、辞書キーまたはセットメンバー(変更されない値は内容によって安全に保存できます)として使用できます。実際に使用するルールの1つは、これから外れます:==(同じ文字)で文字列を比較し、is(メモリ内の同じオブジェクト)で比較しないでください。2つの等しい文字列が1つのオブジェクトを共有するかどうかは、あなたが頼りにできない実装の詳細です。

python
player_name = "太郎"
city = "東京"
note = "It's a great day"
Junoテキスト(str) テキストは引用符、単一または二重、あなたの選択に進みます。一度存在すると、その場で変更することはできません。文字列を編集しているように見えるものはすべて、実際には新しいものをあなたに返します。
Junoテキスト(str) 文字列はイミュータブルです。何もその場でそれらを編集しません、あなたはいつも新しい文字列を返します。メソッドをチェーンし始めた瞬間にそれを念頭に置いてください。
Junoテキスト(str) イミュータブルなUnicodeの実行、`len("café")`は4であり、文字列はdictキーとして機能します。あなたが実際に使う部分:==で比較し、決してisではありません。

整数(int

整数は引用符なしで小数点なしで進みます。Pythonは彼らを整数と呼んでいます。それらは必要なだけ大きくすることができます;Pythonは特別な努力なしに任意に大きな数を処理します。

python
score = 0
age = 28
population = 8_100_000_000   # アンダースコアは読みやすさのためだけです

整数は引用符なしで小数点なしで書かれています。Python整数は任意精度です。RAMを保持できる任意の値に拡張します。CやJavaの32ビットまたは64ビットの固定サイズ整数とは異なります。数値リテラルのアンダースコアはコスメティックであり、Pythonによって無視されます。

python
score = 0
age = 28
population = 8_100_000_000

2つのことは保つ価値があります。まず、Pythonのint任意精度です。RAMを保持できるすべての値を保持するために成長するため、ラップアラウンドやCやJavaのような固定サイズ整数で衝突するエラー(オーバーフロー)がありません。次に、==(等価値)で数字を比較し、is(同じオブジェクト)で比較してください。2つの等しい整数が同じオブジェクトであるかどうかは実装の詳細です。CPython(標準Python)は小さな整数を再利用するため、id(1) == id(1)Trueですが、これは静かに大きな数字を保持するのを止めます。それに基づいて構築しないでください。

python
score = 0
age = 28
population = 8_100_000_000
Juno整数(int) 整数、引用符なし、小数点なし。最良の部分、Pythonintは奇妙なオーバーフローなしであなたが望むほど大きく成長します。8_100_000_000のアンダースコアはそれを読むことができるようにそこにあります。
Juno整数(int) Intは任意精度なので、心配するオーバーフローはありません。数字の多い数字にアンダースコアを使用してください。
Juno整数(int) Intはあなたがメモリ不足になるまで成長するため、オーバーフローは非問題です。保つ価値のある1つの習慣:==で数字を比較し、isではありません。アイデンティティはキャッシング奇妙で、それに依存しません。

小数点(float

小数点を持つ任意の数はfloatです。ほとんどの計算のために期待通りに機能します。1つのこと:いくつかの小数値はバイナリに正確に格納することはできないため、小さな丸め誤差を取得できます:

python
price = 4.99
temperature = 36.6

0.1 + 0.2   # 0.30000000000000004

日常の仕事では、これはめったに重要ではありません。セント分数が数える金銭計算では、Pythonにはdecimalモジュールがあり、それを正しく処理します。これは数字章でカバーされています。

小数点を持つ任意の数はfloatになります。Python floats は倍精度です。約15から17の重要な数字、バイナリに格納されています。そのバイナリストレージは周知のキャッチです:0.1 + 0.20.30000000000000004であり、Pythonのバグではなく、バイナリが小数をどのように表現するかの結果です。お金、または正確な小数が重要な場所ではどこでも、Pythonのdecimalモジュールに到達します。数字章でカバーされています。

python
price = 4.99
temperature = 36.6

フロートはバイナリ(ベース2)に格納され、ほとんどの小数分数、分母が2の力ではない任意の分母(1/10のような)は、バイナリで正確に書くことはできません。これが0.1 + 0.20.30000000000000004になる理由です。本番環境で重要なルール:お金のためにフロートを使用しないでください、または正確な平等のために確認します。正確なベース10の算術が必要な場合はdecimal.Decimalに到達するか、正確な比率のためのfractions.Fraction。どちらもPythonの標準ライブラリ(Pythonに付属するツール)が付属しており、モジュール章でカバーされています。

python
price = 4.99
temperature = 36.6
Juno小数点(float) 小数点はそれをフロートにし、それらは日常のものに問題ありません。古典的なgotcha誰もが一度ヒット:0.1 + 0.20.30000000000000004を与えます。バグではなく、それはバイナリです。お金のために、decimal.Decimalに到達します。
Juno小数点(float) フロートはバイナリであるため、いくつかの小数は正確にすることはできません。`0.1 + 0.2`はかなり`0.3`ではありません。ほとんどの数学に罰金、お金のために決してしません。decimal.Decimalを使用してそれが正確である必要があります。
Juno小数点(float) フロートドリフト、なぜ`0.1 + 0.2`は壊れているように見えるのです。ルール:お金のフロートや正確な平等チェックなし。decimal.Decimal正確なベース10、fractions.Fractionの比率。

真または偽(bool

いくつかのことはオンまたはオフです。Pythonはこれにブール値を使用します。正確に2つの値、TrueFalse。この段階では小さいかもしれませんが、プログラム内のすべての条件と分岐はブール値で実行されます。

python
is_logged_in = True
has_errors = False

Pythonはまた、条件で使用されるときに、特定の値をFalseであるかのように扱います:00.0""、およびNone(Pythonの「ここに価値はありません」)はすべてFalseのように動作します。それ以外のすべてがTrueのように動作します。これは制御フロー章で役立つようになります。

boolは正確にTrueまたはFalseを保持します。これは比較によって返され、条件によって消費されます。Pythonには真実虚偽の値の広いセットがあります。ゼロ値、空のコンテナ、およびNoneは虚偽です;それ以外のすべてが真実です。1つの有用な詳細:boolintのサブクラスであるため、True + True2に評価されます。

python
is_logged_in = True
has_errors = False

boolintの上に構築されています(サブクラス、それは専門とされた種類のintです)、そしてTrueFalseは唯一の2つのboolオブジェクトは、正確に1と0に値を得る存在です。条件では、虚偽の値(偽として数える値)は:ゼロ(00.0)、空のコンテナ(""[](){})、None、およびFalse自体です。それ以外のすべてが真実です。独自のクラスは__bool__または__len__(ダブルアンダースコアで命名されたスペシャル「ダンダー」メソッド)を定義することで、それらの真実性を決定できます。Pythonは、はい・いいえの答えが必要な場合に呼び出すことができます。そしてboolintであるため、isinstance(True, int)Trueです。これは、タイプをチェックするコードであなたを捕まえることができます。

python
is_logged_in = True
has_errors = False
Juno真または偽(bool) 2つの値、TrueFalse、そしてそれらはあなたが書くすべてのifの背後にあります。楽しい部分:0""[]NoneはすべてFalse、残りはすべてTrueを数えます。
Juno真または偽(bool)boolは比較からTrue/Falseです。Pythonはまた真実と虚偽を持っています:空のもの、ゼロとNoneは虚偽です。なぜif my_list:きちんと読むか。
Juno真または偽(bool)boolは秘密裏にintであるため、`isinstance(True, int)`は`True`であり、1日のタイプチェックであなたを驚かせます。虚偽はゼロ、empties and Noneです。カスタムオブジェクトは__bool__または__len__で独自の真実性を選びます。

型のチェックと変換

値の型が確実でない場合、type()がそれを伝えます。値が特定の型かどうかをチェックするために、isinstance()がより信頼できるツールです:

python
print(type("hello"))   # <class 'str'>
print(type(42))        # <class 'int'>
print(type(3.14))      # <class 'float'>
print(type(True))      # <class 'bool'>

isinstance(42, int)    # True
isinstance("hi", str)  # True

type()はオブジェクトの正確な型を返します。独自のコードで型チェックのために、isinstance()が推奨されます。継承を処理し、type()比較は処理しません。

python
print(type(42))          # <class 'int'>
isinstance(True, int)    # True   (boolはintのサブクラス)
type(True) == int        # False  (完全一致のみ、サブクラスなし)

type(x)xの正確な型を与えます。isinstance(x, T)はより多くを行います。MRO方法解決順序継承チェーン(クラスが構築されている親型のライン、x.__class__.__mro__として公開)をPythonが検索する順序付きリスト)を歩くため、親型のためにもTrueを返します。これがisinstance(True, int)Trueboolintの一種)である理由ですが、type(True) == intFalse(完全一致チェック)です。実際のコードでは、型ガードとしてisinstance()に到達します。使用する前に期待する型を確認したチェック。

python
isinstance(True, int)    # True
type(True) == int        # False

Pythonは型を自動的に混合しません。文字列と数値の連結はTypeErrorを発生させます:

python
score = 42
print("Your score is " + score)        # TypeError
print("Your score is " + str(score))   # works

型名を関数として使用して明示的に変換します:

呼び出し結果
str(42)"42"
int(3.9)3(丸めず、切り詰めます)
float("3.14")3.14
int("3.14")ValueError:小数点文字列をintに直接変換することはできません
int(float("3.14"))3(最初にfloatに変換し、次にint)
bool(0) / bool("")False
Juno型のチェックと変換type()は何かを伝え、isinstance()は与えられた型かどうかをチェックします。そしてPythonは文字列と数値を接着しません。`str()`または`int()`で最初に変換してください。誰もが一度それを尻に落とします。
Juno型のチェックと変換type() ==から`isinstance()`に到達し、継承を尊重します。変換は常に明示的です。文字列と数値を連結する前に変換してください。
Juno型のチェックと変換 `isinstance()`はあなたの型ガード、クラスツリーに従って`type(x) == T`は正確にのみ一致します。変換を明示的に保つ、`int("3.14")`の方が推測するより高いでしょう。最初に`float`を通してください。

実装で

小さなスクリプトで一緒に働く4つの型。出力行はf-stringsを使用してテキストに値を埋め込みます。開いている引用符の前にfを入れて、変数を{}で包みます。Pythonはそれを変数の実際の値に置き換えます。あなたはそれらを次の章で適切に学びます。

python
player_name = "太郎"
level = 3
accuracy = 0.94
is_premium = True

print(f"{player_name} is on level {level} with {accuracy:.0%} accuracy.")
print(f"Premium account: {is_premium}")

型は重要です。level + 1が機能し、player_name + 1は機能しないため。各変数は正確に1種類のことを保持します;Pythonはそれらをあなたのために静かに混合しません。

4つの型すべての実際の構成ブロック、ランタイム状態から分離された定数。f"..."構文はf-stringです。{}内の任意の式は実行時に評価され、出力に埋め込まれます。出力と入力章で完全にカバーされています。

python
BASE_URL = "https://api.example.com"
MAX_RETRIES = 3
DEBUG = False

user_name = "太郎"
request_count = 0
last_response = None

request_count += 1
print(f"[{request_count}] {BASE_URL} | debug={DEBUG}")

Noneは「ここに価値がまだない」のための標準的なプレースホルダーです。その型はNoneTypeで、条件で虚偽のように動作します。プログラムで後で意味を持つまで、変数のデフォルトとして使用します。

インライン型アノテーションで同じ構成。アノテーションは、名前が保持することを期待する型を記録します。型チェッカーとエディタ(IDE)のために存在し、Pythonはプログラム実行中にそれを無視します:

python
BASE_URL: str = "https://api.example.com"
MAX_RETRIES: int = 3
DEBUG: bool = False

user_name: str = "太郎"
request_count: int = 0
last_response: str | None = None

str | Noneユニオン型で、Python 3.10で追加されました。値が文字列またはNoneのいずれかであることを言っています。古いバージョンでは、typingモジュールからインポートされたOptional[str]として同じことを書きます。str | Noneフォームは、最小バージョンが許可されるときはいつでもモダンPythonで好まれる1つです。