お聞ききしたいこと
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クラスとの継承との関係性が全くイメージがわきません…
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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
0
こちらのリンクを貼っておきます。
http://blog.lerner.co.il/pythons-objects-and-classes-a-visual-guide/
投稿2018/02/16 03:33
総合スコア8560
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/02/17 00:52
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
総合スコア18392
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
わたくしもちゃんと理解しているわけではないのですが、Pythonでは「型」は単なる「型」ではなく「型オブジェクト」なんですよね。(参考:型オブジェクト)
試しにtype
自身が何者かと探ってみると以下のようになります。ご覧の通りにtype
自身もオブジェクトの体をなしています。
しかもtype(type) is type
やisinstance(type, type)
がTrue、つまり型オブジェクトの型は型オブジェクト自身という、型を追いかけても物事が堂々巡りしたりします。(多分PyType_Type
に帰着しているんだと思いますが。)
また以下は別の例で、整数(=0)の型はint型で、そのint型の型はtypeという事を示しています。
これらを踏まえると、、、
質問①への(未)回答
現時点で厳密に「その理解が正しい 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総合スコア6142
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/02/15 13:21
退会済みユーザー
2018/02/15 14:26 編集
2018/02/15 14:22
2018/02/15 14:44
退会済みユーザー
2018/02/15 15:06