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

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

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

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

Python

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

Q&A

解決済

2回答

1591閲覧

python3.9のインスタンス作成後にtypeがNone Typeになってしまう原因

sequelanonymous

総合スコア123

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2021/04/17 08:01

スペシャルメソッドを挙動を確認しています。

クラスのインスタンス化するときは、カッコつきでインスタンス化するはずですが、type()の結果がNone Typeになり、カッコなしでインスタンス化した場合には、type()がtypeになります。

なぜ、カッコつきでインスタンス化できないのか、またカッコなしでインスタンス化したときの<class 'type'>は何を指しているのか、についてご教示いただけませんでしょうか?

__call__メソッドについても勉強していますが、なんのために存在し、どう利用できるかも理解できずにいます。
__init__とnewの違いは理解しています。

読んだ記事のURL:

python

1class SpecialMethods: 2 print("class variable") 3 4 def __init__(self): 5 print("print method in __init__") 6 7 def __new__(self): 8 print("print method in __new__") 9 10 def __call__(self): 11 print("print method in __call__")

実行結果

$ python Python 3.9.2 (v3.9.2:1a79785e3e, Feb 19 2021, 09:06:10) [Clang 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from xxx import SpecialMethods class variable >>> cls = SpecialMethods() print method in __new__ >>> type(cls) <class 'NoneType'> >>> cls = SpecialMethods >>> type(cls) <class 'type'>

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

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

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

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

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

meg_

2021/04/17 08:18

> initとnewの違いは理解しています。 どのように理解されていますか?
sequelanonymous

2021/04/17 08:30

initの前の処理されるスペシャルメソッドと理解しています。newで返した値がinitに渡されてinitで処理されるという理解でいます。当質問の回答と関連する箇所でしょうか?
meg_

2021/04/17 08:48

> newで返した値がinitに渡されてinitで処理されるという理解でいます。当質問の回答と関連する箇所でしょうか? 既に回答が付いていますが、上記文章と質問のコードとの差異が答えそのものかと思います。
guest

回答2

0

「newで返した値がinitに渡されてinitで処理されるという理解でいます。」と書かれているとおり、___new___はインスタンス生成前に呼ばれて、インスタンスを生成して返すのが仕様ですが、提示のコードは何も返していません。 なので、呼んでもインスタンスが生成されないのです。

python

1 def __new__(cls): 2 print("print method in __new__") 3 self = super().__new__(cls) 4 return self

このように書き換えれば正常に動作します。
また、インスタンスを生成すると___init___も呼ばれるようになります。

__call__については、「インスタンスが関数として呼ばれたときにどのような動作をするか」を定義するものです。どのように使うかは設計によります。

投稿2021/04/17 08:41

編集2021/04/17 09:26
TakaiY

総合スコア12801

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

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

ppaul

2021/04/17 09:12

インスタンス生成前に呼ばれるのは__new__の方ですね。
TakaiY

2021/04/17 09:26

ああ、そうですね。 修正しました。
sequelanonymous

2021/04/17 15:01

ご回答ありがとうございます!callについても理解しました。一点ご確認させてください。 > _new_はインスタンス生成前に呼ばれて、インスタンスを生成して返す ここでいうインスタンスとは、SpecialMethodsクラスがインスタンス化する前に呼ばれて、インスタンス化されたあとに_new_の返り値が返る。 そのため、 self = super().__new__(cls)を追記することで継承している基底クラスのnew関数に引数としてこのクラスが継承したクラスのnew関数にわたし、先に継承もとののnew関数を実行することでインスタンス化される、という理解であっていますでしょうか?
TakaiY

2021/04/17 15:23

基本的には合ってます。 pythonでクラスのインスタンスを生成する方法がわかるのであれば、親クラス(基底クラスでなく)の__new__は呼ばなくてはならないわけではありません。ただ、通常はそにょうな方法でクラスをインスタンス化します。
guest

0

ベストアンサー

TakaiYさんの回答の補足です。

カッコつきでインスタンス化できないのか

インスタンス化はある意味ではしています。
__new__が値を返していないというのは、Noneを返しているのと同じです。

python

1>>> class SpecialMethods: 2... print("class variable") 3... def __init__(self): 4... print("print method in __init__") 5... def __new__(self): 6... print("print method in __new__") 7... def __call__(self): 8... print("print method in __call__") 9... 10class variable 11>>> sm = SpecialMethods() 12print method in __new__ 13>>> sm == None 14True
カッコなしでインスタンス化したときの<class 'type'>は何を指しているのか

カッコなしでインスタンス化はしていません。
SpecialMethodsというクラスの型はtypeであるということを示しています。

callメソッドについても勉強していますが、なんのために存在し、どう利用できるかも理解できずにいます。

TakaiYさんの修正後のクラスで以下のようにやってみれば意味はわかると思います。

python

1>>> class SpecialMethods2: 2... print("class variable") 3... def __init__(self): 4... print("print method in __init__") 5... def __new__(cls): 6... print("print method in __new__") 7... self = super().__new__(cls) 8... return self 9... def __call__(self): 10... print("print method in __call__") 11... 12class variable 13>>> sm = SpecialMethods2() 14print method in __new__ 15print method in __init__ 16>>> sm() 17print method in __call__

投稿2021/04/17 09:21

編集2021/04/17 09:26
ppaul

総合スコア24666

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

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

sequelanonymous

2021/04/17 15:20 編集

一つ一つご回答ありがとうございます!いくつかご確認させてください。 もともとのコードでpythonコンソールをつかって確認しています。 >>> from singleton import SpecialMethods class variable >>> s = SpecialMethods >>> a = SpecialMethods() method in __new__ >>> s <class 'singleton.SpecialMethods'> >>> s == None False >>> a >>> type(s) <class 'type'> >>> type(a) <class 'NoneType'> >>> s() method in __new__ 1) そもそも、importしただけでなぜprint文がアウトプットされるのがきになっています。 2) カッコなしでインスタンス化できないということでしたが、上記のアウトプットのようにNoneでfalseにはならず、これはなにをアウトプットしているのか気になっています。 3) カッコなしで変数sにいれたあと、 s()と実行すると、newの関数がよばれてます。これは、インスタンス化されていないとなると、何がおきていることになりますでしょうか? 4) 公式ドキュメントでもクラスの型としてのtypeを探しているのですが、見当たらずでして、もし理解の手助けになりそうなURLなどがありましたらご教示いただけますと助かります。 すみません、長文になってしまいましたが、この辺いつもあやふやにしていたのでいい加減ちゃんと理解しておきたいなと思い、ご質問させていだたきました!お手すきのさいにでもお答えいただけますと助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問