Pythonのtypesモジュールの使い方を初心者向けに解説!SimpleNamespaceや型判定の基本

公開日: 2026-05-25

Pythonを学んでいると、int、str、list のような型はよく見かけます。 ですが、少し学習が進むとtypesという標準ライブラリに出会って、これは何に使うのだろうと感じる方も多いのではないでしょうか。

結論から言うと、Pythonの types モジュールは 型に関する便利な道具をまとめた標準ライブラリ です。普段の入門コードではあまり目立ちませんが、オブジェクトの種類を調べたり、簡単なデータ入れ物を作ったり、読み取り専用の辞書ビューを作ったりするときに役立ちます。

この記事では、IT初心者の方にもわかるように、Pythonの types の使い方をやさしく解説します。

Pythonのtypesモジュールとは

Pythonのtypesモジュールは、Pythonに最初から入っている標準ライブラリの1つです。追加インストールは不要で、import typesと書くだけで使えます。

公式ドキュメントでは、typesは動的な型作成を助ける関数や、Pythonインタプリタで使われる一部の型名、型に関するユーティリティを提供するモジュールとして説明されています。 つまり、型そのものを扱うための補助ツール集と考えるとわかりやすいです。

まずは、読み込み方を見てみましょう。

import types

print(types)

typesは標準ライブラリなので、pip installなどは必要ありません。Pythonをインストールしていれば、すぐに使えます。

ただし、初心者の方に最初に伝えたいのは、types は毎日必ず使うモジュールではないということです。 まずは int、str、list、dict、関数、クラスといった基本を理解したあとに触れると、かなり理解しやすくなります。

type関数とtypesモジュールの違い

名前が似ているので、typetypesを混同しやすいです。ここは最初に整理しておきましょう。

typeはPythonの組み込み関数です。値の型を調べたり、クラスを動的に作ったりできます。

一方でtypesは標準ライブラリのモジュールです。FunctionTypeやSimpleNamespaceのように、型に関係する部品がいくつも入っています。

表にすると、違いは次のようになります。

名前 種類 主な使い方 初心者向けの理解
type 組み込み関数 値の型を調べる これは何型かを確認する関数
types 標準ライブラリ 型関連の便利機能を使う 型に関する道具箱
typing 標準ライブラリ 型ヒントを書く コードの意図を伝えるための型情報

type、types、typing は名前が似ていますが、役割は違います。特にtypingは型ヒントでよく使うため、typesと分けて理解しておくと混乱しにくいです。

【関連記事】Pythonの型ヒントをどうやって使うの?リーダブルコードに必須な型チェック

まずはtype関数で型を確認してみる

types モジュールに入る前に、まず type関数で型を確認してみましょう。Pythonでは、あらゆる値が何らかの型を持っています。

print(type(123))
print(type("hello"))
print(type([1, 2, 3]))
print(type({"name": "Taro"}))

実行すると、次のような結果になります。

<class 'int'>
<class 'str'>
<class 'list'>
<class 'dict'>

intは整数、strは文字列、listはリスト、dictは辞書です。 Pythonでは、これらもすべてオブジェクトとして扱われます。

ここで大切なのは、Pythonでは型もプログラム上で扱えるという感覚です。 typesモジュールは、この型の世界を少し便利に扱うための道具だと思ってください。

typesでよく使うもの一覧

typesモジュールには多くの名前が用意されています。ですが、初心者がすべて覚える必要はありません。

まずは、実用的に見かけやすいものを表で確認しましょう。

名前 役割 使いどころ
types.SimpleNamespace 属性でアクセスできる簡単なオブジェクトを作る テストデータや設定値の入れ物
types.MappingProxyType 辞書を読み取り専用のように扱う 設定値の保護、公開用ビュー
types.FunctionType 関数オブジェクトの型 関数かどうかの判定
types.LambdaType lambdaで作られた関数の型 ラムダ式を含む関数判定
types.ModuleType モジュールの型 モジュールかどうかの確認
types.NoneType None の型 Noneを型として扱いたい場合

この中でも、初心者にとって理解しやすく、実用イメージが湧きやすいのは SimpleNamespaceとMappingProxyTypeです。 この記事でも、この2つを中心にしつつ、型判定に関係するものを紹介します。

SimpleNamespaceの使い方

SimpleNamespaceは、簡単なオブジェクトを作るためのクラスです。 辞書のようにデータを持てますが、ドットで属性にアクセスできるのが特徴です。

まずは、基本的な使い方を見てみましょう。

from types import SimpleNamespace

user = SimpleNamespace(name="Taro", age=30)

print(user.name)
print(user.age)

実行結果は次のようになります。

Taro
30

辞書ならuser["name"]のように書きますが、SimpleNamespaceではuser.nameと書けます。コードが少し自然な文章のように読めますね。

辞書との違い

SimpleNamespaceは辞書に似ていますが、まったく同じものではありません。 辞書はキーで値にアクセスし、SimpleNamespaceは属性で値にアクセスします。

比較してみると、違いがわかりやすいです。

from types import SimpleNamespace

user_dict = {"name": "Taro", "age": 30}
user_obj = SimpleNamespace(name="Taro", age=30)

print(user_dict["name"])
print(user_obj.name)

どちらも Taro を取り出せます。ですが、書き方が違います。

表で整理すると、次のようになります。

項目 dict SimpleNamespace
アクセス方法 user["name"] user.name
キーの自由度 文字列以外も使える 属性名として使える名前が基本
用途 汎用的なデータ管理 簡単なオブジェクト風のデータ
初心者へのおすすめ まず覚えるべき基本 補助的に使うと便利

基本はdictを覚えるべきです。 SimpleNamespaceは、ちょっとした設定やテスト用データを見やすく持ちたいときに使うと便利です。

エンジニア歴10年の私の経験では、SimpleNamespaceは本番の複雑なデータ設計よりも、テストコードやサンプルコードで力を発揮する印象があります。 簡単なモックデータを作るときに、読みやすく書けるからです。

後から属性を追加できる

SimpleNamespaceは、作ったあとから属性を追加できます。これも初心者にとってわかりやすい特徴です。

from types import SimpleNamespace

user = SimpleNamespace(name="Taro")
user.age = 30
user.country = "Japan"

print(user)

実行結果は次のようになります。

namespace(name='Taro', age=30, country='Japan')

このように、user.ageuser.countryのように後から追加できます。 ちょっとしたデータの入れ物としては便利です。

ただし、何でも後から足せるということは、構造が曖昧になりやすいということでもあります。 大きなアプリケーションでは、dataclassや通常のクラスを使ったほうが安全なことも多いです。

【関連記事】Pythonの変数は箱じゃない?メモリ上のラベルという正体を理解する

MappingProxyTypeの使い方

次に、MappingProxyType を見ていきます。これは、辞書の読み取り専用ビューを作るためのクラスです。

読み取り専用と聞くと少し難しそうですが、要するに外から勝手に変更されたくない辞書を見せるための仕組みです。

from types import MappingProxyType

settings = {
    "debug": False,
    "version": "1.0.0",
}

readonly_settings = MappingProxyType(settings)

print(readonly_settings["debug"])
print(readonly_settings["version"])

このコードでは、settings という辞書をもとに readonly_settingsを作っています。readonly_settingsから値を読むことはできます。

では、変更しようとするとどうなるでしょうか。

from types import MappingProxyType

settings = {
    "debug": False,
    "version": "1.0.0",
}

readonly_settings = MappingProxyType(settings)

readonly_settings["debug"] = True

このコードを実行すると、エラーになります。MappingProxyType で作ったオブジェクトには、直接代入できません。

実務では、設定値や定数のように、他の場所から書き換えてほしくないデータを渡すときに考え方として役立ちます。完全な防御というより、変更してはいけない意図をコードで表すイメージです。

元の辞書を変えると反映される

MappingProxyTypeで注意したいのは、元の辞書を変更すると、その変更は反映されるという点です。コピーではなく、元の辞書を参照するビューだからです。

from types import MappingProxyType

settings = {"debug": False}
readonly_settings = MappingProxyType(settings)

print(readonly_settings["debug"])

settings["debug"] = True

print(readonly_settings["debug"])

実行結果は次のようになります。

False
True

readonly_settings自体からは変更できません。ですが、元の settingsを変更すると、readonly_settingsで見える値も変わります。

ここは勘違いしやすいです。外部に見せる側を読み取り専用にしたいのか、元データも含めて完全に固定したいのかを分けて考えましょう。

FunctionTypeで関数かどうかを調べる

types モジュールには FunctionType という名前もあります。これは、ユーザーが定義した関数の型を表します。

関数かどうかを調べたいときに使えます。

from types import FunctionType

def hello():
    print("hello")

print(type(hello))
print(isinstance(hello, FunctionType))

実行結果は次のようになります。

<class 'function'>
True

helloは関数なので、FunctionTypeと判定されます。isinstanceを使うと、指定した型のオブジェクトかどうかを確認できます。

ただし、実務では関数かどうかの判定にはcallableを使うことも多いです。callableは、呼び出せるオブジェクトかどうかを調べます。

def hello():
    print("hello")

class Greeter:
    def __call__(self):
        print("hi")

greeter = Greeter()

print(callable(hello))
print(callable(greeter))

実行結果はどちらも Trueです。関数だけでなく、__call__を持つオブジェクトも呼び出せるからです。

FunctionTypeは関数そのものを見たいとき、callableは呼び出せるかどうかを見たいとき、と考えると整理しやすいです。

LambdaTypeの使い方

LambdaTypeは、lambdaで作られた関数の型です。実は、通常の関数とlambdaはかなり近い存在です。

次のコードを見てみましょう。

from types import FunctionType, LambdaType

def add_one(x):
    return x + 1

add_two = lambda x: x + 2

print(isinstance(add_one, FunctionType))
print(isinstance(add_two, LambdaType))
print(FunctionType is LambdaType)

実行すると、どちらも関数として扱われることがわかります。FunctionTypeとLambdaTypeは同じ型として扱われます。

lambda は短い関数をその場で書きたいときに便利です。 ですが、初心者のうちは無理に使いすぎる必要はありません。

読みやすさを優先するなら、defで名前を付けた関数にしたほうがよい場面も多いです。実務では、短く書けることより、あとから読んで理解しやすいことのほうが大切です。

【関連記事】ラムダ式(無名関数)を使いこなす。コードを極限までシンプルにする方法を解説

ModuleTypeでモジュールかどうかを確認する

ModuleTypeは、モジュールの型を表します。モジュールとは、Pythonファイルや標準ライブラリのように、機能をまとめたものです。

たとえば、mathモジュールを調べてみましょう。

import math
from types import ModuleType

print(type(math))
print(isinstance(math, ModuleType))

実行結果は次のようになります。

<class 'module'>
True

mathはモジュールなので、ModuleTypeと判定されます。普段はあまり直接使いませんが、動的に読み込んだものがモジュールかどうか確認したい場面で役立ちます。

たとえば、プラグイン機構や自作ツールで外部ファイルを読み込むような設計では、ModuleTypeの考え方が出てくることがあります。初心者のうちは、モジュールにも型があるのだと知っておくだけでも十分です。

NoneTypeの使い方

NoneType は、Noneの型を表します。Python 3.10以降ではtypes.NoneTypeとして使えます。

Noneは値がないことを表す特別なオブジェクトです。空文字や0とは違います。

from types import NoneType

value = None

print(type(value))
print(isinstance(value, NoneType))

実行結果は次のようになります。

<class 'NoneType'>
True

ただし、Noneかどうかを判定するだけなら、通常はis Noneを使います。

value = None

if value is None:
    print("値がありません")

これはPythonでとてもよく使われる書き方です。NoneTypeを直接使う場面は多くありません。

エンジニア歴10年の現場感としても、None判定はis Noneが基本です。NoneTypeは、型をプログラム上で明示的に扱う必要があるときだけ出番があります。

【関連記事】Noneはただの空ではない。Pythonに1つしか存在しないシングルトンの正体とは?

typesとisinstanceを組み合わせる

types モジュールの型名は、isinstanceと組み合わせると理解しやすいです。isinstanceは、オブジェクトが特定の型かどうかを調べる関数です。

from types import FunctionType, ModuleType
import math

def greet():
    print("hello")

print(isinstance(greet, FunctionType))
print(isinstance(math, ModuleType))
print(isinstance(123, FunctionType))

実行結果は次のようになります。

True
True
False

greetは関数、mathはモジュール、123は関数ではありません。このように、typesにある型名を使うと、Python内部のオブジェクトの種類を確認しやすくなります。

ただし、型判定に頼りすぎるとコードが硬くなることもあります。Pythonでは、実際に必要な操作ができるかを重視する考え方もあります。

たとえば、関数型かどうかよりも、呼び出せるかどうかが重要ならcallableを使ったほうが自然です。どの判定が目的に合っているかを考えることが大切です。

typesを使わないほうがよい場面

typesは便利ですが、何でもtypesで解決しようとする必要はありません。初心者のうちは、むしろ基本機能で書いたほうが読みやすいことも多いです。

たとえば、値が文字列かどうかを確認したいなら、typesは不要です。

name = "Taro"

print(isinstance(name, str))

strは組み込み型なので、そのまま使えます。int、list、dict なども同じです。

また、None判定なら次のように書きます。

value = None

if value is None:
    print("値がありません")

このように、普段のコードでは組み込み型や標準的な書き方で十分なことが多いです。typesは、標準の名前では直接扱いにくい型や、少し特殊なユーティリティを使いたいときに登場します。

typesとtypingの違い

Pythonで型の話を調べていると、typesだけでなくtypingも出てきます。ここはかなり混乱しやすいポイントです。

typesは、実行中のPythonオブジェクトの型や型関連ユーティリティを扱います。typingは、コードを書くときに型ヒントを付けるために使います。

次の例を見てみましょう。

from typing import Callable

def run_task(task: Callable[[], None]) -> None:
    task()

このコードのCallableは、task が呼び出せるものだと示す型ヒントです。実行時に関数かどうかを判定しているわけではありません。

一方で、types.FunctionType は実行中のオブジェクトが関数型かどうかを確認するときに使えます。

from types import FunctionType

def hello():
    print("hello")

print(isinstance(hello, FunctionType))

ざっくり言うと、typingはコードを読む人や型チェッカーに意図を伝えるためのものです。typesは実行時に型そのものを扱うためのものです。

まとめ

Pythonの types モジュールは、型に関する便利な道具をまとめた標準ライブラリです。 最初は少し難しく見えますが、SimpleNamespaceやMappingProxyTypeから触れると実用イメージがつかみやすくなります。

SimpleNamespaceは、属性アクセスできる簡単なオブジェクトを作りたいときに便利です。テスト用データや小さな設定オブジェクトを作る場面で役立ちます。

MappingProxyTypeは、辞書を読み取り専用のように見せたいときに使えます。ただし、元の辞書を変更すると反映されるため、完全な不変データとは違う点に注意しましょう。

FunctionType、LambdaType、ModuleType、NoneType などを知ると、Pythonでは関数やモジュール、Noneにも型があることが見えてきます。これはPythonのオブジェクト指向的な仕組みを理解するうえで、とても良い入口になります。

初心者のうちは、typesを丸暗記する必要はありません。まずは type、isinstance、callable と組み合わせながら、Pythonの型の世界に少しずつ慣れていきましょう。

ここまでお読みいただきありがとうございました。

Pythonの基礎から応用まで学べる
Python WebAcademy

Python WebAcademyでは、Pythonの基礎からアーキテクチャなどの応用的な内容まで幅広く学べます。
また、ブラウザ上で直接Pythonコードを試すことができ、実践的なスキルを身につけることが可能です。

Pythonの学習を始める