質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

4回答

2326閲覧

Python3のオブジェクトに関して(型、継承など)

sabx

総合スコア200

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

5グッド

6クリップ

投稿2018/02/14 06:44

編集2018/02/14 06:45

お聞ききしたいこと

Python3では、すべてがオブジェクトであるというのを参考書やWebで見てみて、疑問に思った点があるので、質問させてください。

質問① 型という概念に関して

型というのは、インスタンスオブジェクトのひな型となる class のことをさしているという認識で問題ないでしょうか。

質問② モジュール自体の型に関して

test.pyというモジュールを自作し、importした後に type(test) で確認すると、 <class 'module'> と表示されるかと思います。
これは、モジュール自体が moduleクラスのインスタンスであるという認識で問題ないでしょうか。
(+α)module クラスオブジェクトの型を調べようとして、type(module) を実施しましたが、下記エラーになってしまいました。
自分の想定では、すべてのクラスオブジェクトは type クラスのインスタンスだと思っていたので、<class 'type'> と表示される想定でしたが、、、

Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'builtin_function_or_method' is not defined
質問③ クラスオブジェクトの型とobjectクラスの継承に関して

クラスオブジェクトの実態は、typeクラスのインスタンスであるかと思いますが、
objectクラスとの継承との関係性が全くイメージがわきません…

ykws, umyu, LouiS0616, namnium1125👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

Fluent Pythonから引用しながらお答えします。

質問① 型という概念に関して

少し長いですが、Fluent Python p.776の"型(type)"の用語説明を引用します。

...型にはユーザ定義のものとインタプリタに組み込まれたもの(組み込み型)があります。型とクラスの統合の転機となったPython 2.2以前は、型とクラスは異なるエンティティで、ユーザー定義クラスでは組み込み型を拡張できませんでした。それ以降、組み込み型と...クラスは互換となり、クラスはtypeのインスタンスとなりました。

とありますので、最新のPythonを使っていれば型とクラスは同じものと考えてよさそうです。

質問② モジュール自体の型に関して

次にこちらを探ってみましょう。これを検証するために、Fluent Pythonで紹介されている方法を使ってみます。Fluent Python, p372より

クラスには__mro__という属性があり、ここにそのクラスからobjectクラスまでの順にスーパークラスへの参照のタプルが収容されています.

ということなので、各オブジェクトの__mro__という属性を調べればよさそうです。
試しにに、boolクラスの__mro__を覗いてみましょう。

python

1>>> bool.__mro__ 2(<class 'bool'>, <class 'int'>, <class 'object'>)

この__mro__の最初の要素は自分自身なので、二番目以降がスーパークラスになります。boolはintクラスからobjectクラスを継承していることが分かりますね(ただし、多重継承している場合は話が違ってきますが割愛)。これを利用して次のような関数を作ってクラスの継承関係を探ってみましょう。

python

1def print_mro(cls): 2 print(', '.join(c.__name__ for c in cls.__mro__))

先程のboolクラスをprint_mroで調べてみると次のようになります。

python

1>>> print_mro(bool) 2bool, int, object

確かに同じ結果になりました。これでmoduleクラスを調べてみると、

python

1>>> print_mro(type(test)) 2module, object

と言うわけで、moduleクラスはobjectクラスを継承しているだけのようですね。moduleクラスとインスタンスの関係はKSwordOfHasteのおっしゃっている通りかなと思います。

質問③ クラスオブジェクトの型とobjectクラスの継承に関して
クラスオブジェクトの実態は、typeクラスのインスタンスであるかと思いますが、
objectクラスとの継承との関係性が全くイメージがわきません…

さて、ここは正直全く説明できません。推移律を満たすかどうかなどの議論はKSwordOfHasteのおっしゃる通りかと思います。どの程度謎めいているかを示すために、Fluent Python p.700の次の説明(?)を引用します。

objectクラスとtypeクラスには、objectがtypeのインスタンスで、かつtypeがobjectのサブクラスという得意な関係があります。この関係は「魔法」です。どちらのクラスも他方をテギできる前に存在していなければならないため、Pythonではこの関係を表現できません。typeがそれ自体のインスタンスである点もかなり魔術的です。

同ページにクラス図が載っていますが、僕には何ともうまく説明できません。鶏が先か卵が先か・・・という議論になりそうです。ご興味があれば一度覗いてみてください。

投稿2018/02/14 14:30

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sabx

2018/02/15 13:21

ご回答していただきましてありがとうございます…! 古いpythonだと「組み込み型」「クラス型」のようにわかれていたのですね…(Javaでいうプリミティブ型と参照型とかかな…)
退会済みユーザー

退会済みユーザー

2018/02/15 14:26 編集

要らぬことを書いたのようなので削除。
LouiS0616

2018/02/15 14:22

Java ・プリミティブ型... 値そのものが保管される型。intなど。 ・参照型... 参照値が保管される型。Integer, Stringなど。Cでいうポインタ型 Python ・旧スタイルのクラス... objectを基底に持たない型。 ・新スタイルのクラス... objectを基底に持つ型。 一般的な話 ・ミュータブル... 要素の変更を許す。 ・イミュータブル... 要素の変更を許さない。 関連がないわけではないですが、分類の軸が違います。
sabx

2018/02/15 14:44

コメントありがとうございます! 確かに分類の軸が異なりますね…!検討違いのことを考えてしまっていました(ご指摘ありがとうございます)
退会済みユーザー

退会済みユーザー

2018/02/15 15:06

@LoisS0616 さん。フォローありがとうございます。分類の軸が違うのは承知しているのですが、関数の引数として渡した時の振る舞いが似ているかと思って列挙しました。
guest

0

こちらのリンクを貼っておきます。
http://blog.lerner.co.il/pythons-objects-and-classes-a-visual-guide/

投稿2018/02/16 03:33

mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

0

ベストアンサー

Pythonの型システムについてきちんと把握しているわけではないので間違ってたらすみません。

インスタンスオブジェクトのひな型となる class のことをさしているという認識で問題ないでしょうか。

Pythonの全てのデータが何かのクラスのインスタンスであるのが正しいのならYESといってよいと思います。(イマイチ煮え切らない答えになっている理由は言語によって「クラスのインスタンスとは言えないデータも言語仕様に含まれていることがある」からです。Javaなどですと「プリミティブ型と参照型」の分類があり後者は「型=クラス」なのですが前者は「型=組み込み型ではあるがクラスではない」というふうになっています。)

モジュール自体が moduleクラスのインスタンスであるという認識で問題ないでしょうか。

そう捉えるのが自然ですし、正しいといってよいと思います。

type(module)

さてmoduleというのは名前です。その名前が何を意味するかが問題ですね。import test.pyとした後にtestという名前はモジュールを表すのは確実と思います。しかし、「module」という名前がそのままモジュールというクラスを表すかどうかは文脈によるのではないでしょうか?それを避けてtestというモジュールオブジェクトの型が何かを調べるには

type(type(test))

とやった方が確実だろうと思います。実際そうやってみると結果は

<class 'type'>

になりますね。

クラスオブジェクトの実態(=×、正しい漢字は実体)は、typeクラスのインスタンスであるかと思いますが、objectクラスとの継承との関係性が全くイメージがわきません…

オブジェクト指向システムを学び始めのころ重要な2つの関係について混同しがちだと思いますがそれを区別できれば混乱が解消できると思います。それは

(A) クラスとインスタンスの関係(あるオブジェジェクトの型が何かという関係)
(B) 継承関係(クラスどうしの関係)

1 is instance of intクラス (A1)
intクラス is instance of typeクラス
objectクラス is instance of typeクラス

intクラス is derived from objectクラス (B1)
typeクラス is derived from objectクラス

(A1)と(B1)を合わせて1 is a objectと言ったりしますがこの表現は(A)と(B)の両方の意味合いを含んでいるということを理解する必要があります。

1 is instance of intクラスでありintクラス is instance of typeクラスなのですが、もちろん1 is not a instance of typeクラスです。

(A)の関係は推移律を満たしません。a1がa2のインスタンスでa2がa3のインスタンスであるときa1はa3のインスタンスではありません。
一方(B)は推移律を満たします。b1がb2の派生でありb2がb3の派生ならb1はb3の派生です。

このようにこの2つの関係は別の概念なので、それらをきちんと区別すれば見えてくると思います。

投稿2018/02/14 07:42

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

わたくしもちゃんと理解しているわけではないのですが、Pythonでは「型」は単なる「型」ではなく「型オブジェクト」なんですよね。(参考:型オブジェクト

試しにtype自身が何者かと探ってみると以下のようになります。ご覧の通りにtype自身もオブジェクトの体をなしています。
What's type in Python

しかもtype(type) is typeisinstance(type, type)がTrue、つまり型オブジェクトの型は型オブジェクト自身という、型を追いかけても物事が堂々巡りしたりします。(多分PyType_Typeに帰着しているんだと思いますが。)

また以下は別の例で、整数(=0)の型はint型で、そのint型の型はtypeという事を示しています。
Type of int

これらを踏まえると、、、

質問①への(未)回答

現時点で厳密に「その理解が正しい or 間違えている」と確定させないほうが良いと思います。PythonにはDuck Typingという考え方もあるので、型に関しては突き詰めずにゆるく考えて、色々と分かってきてから改めて掘り起こすほうが良いと思います。(わたくしが「XYZがPythonにおける型の概念です」と説明できないだけですが。)

質問②への回答

モジュールの型はtypes.ModuleTypeです。以下は検証コードです。

python

1import os 2import types 3 4print(type(os) is types.ModuleType)

追記:モジュール型の型はtypeつまり<class 'type'>です。

python

1print(type(type(os))) # -> <class 'type'>

質問③への(未)回答

摩訶不思議ですがtype(object) is typeもTrueになるんですよね。多分この文書で解説されている内容と,そこに載っているPyObjectの宣言が、突き進むためのヒントになるのではないでしょうか。

C

1typedef struct _object { 2 Py_ssize_t ob_refcnt; 3 struct _typeobject *ob_type; 4} PyObject;

投稿2018/02/14 08:04

編集2018/02/14 08:12
YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sabx

2018/02/17 00:57

ご回答ありがとうございます! 「型オブジェクト」なるものが存在しているのですね、、、 自分の意識だと、「型オブジェクト」 = 「Classオブジェクト」 = 「typeクラスインスタンス」 かと思っていましたが、記載のリンクを見てみると全然違うことが書いてあるように見えました。笑
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問