0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonでメソッド呼び出しに()つけ忘れたら変な動きになった話

Posted at

Pythonでメソッド呼び出しに()つけ忘れたら変な動きになった話

なんか挙動がおかしかったのでコードを追っかけたらメソッド呼び出しに()がついてなくて、それなのにtry-ExceptionのException側に落ちてなかったのであれっと思って調べた話

サンプルコード

# util class
class utilclass:
    # local value
    class_value=True
    # getter
    def get_class_value(self):
        return self.class_value
    # setter
    def set_class_value(self,argv):
        self.class_value=argv
# main method
def main():
    # instance
    myutil = utilclass()
    # test-1
    print("--- test-1 ---")
    print(str(type(myutil.get_class_value())))
    print(myutil.get_class_value())
    # test-2
    print("--- test-2 ---")
    myutil.set_class_value(False)
    print(str(type(myutil.get_class_value())))
    print(myutil.get_class_value())
    # test-3
    print("--- test-3 ---")
    print(str(type(myutil.get_class_value)))
    print(myutil.get_class_value)
    # test-4
    print("--- test-4 ---")
    if (myutil.get_class_value):
        print("Class Value is True")
    else:
        print("Calss Value is False")
# call main method
if __name__ == '__main__':
    main()

結果

--- test-1 ---
<class 'bool'>
True
--- test-2 ---
<class 'bool'>
False
--- test-3 ---
<class 'method'>
<bound method utilclass.get_class_value of <__main__.utilclass object at 0x785fe4d8a030>>
--- test-4 ---
Class Value is True

各比較

test-1

    # test-1
    print("--- test-1 ---")
    print(str(type(myutil.get_class_value())))
    print(myutil.get_class_value())

これに対して

--- test-1 ---
<class 'bool'>
True

こうなっているのでおかしな点は無し

test-2

    print("--- test-2 ---")
    myutil.set_class_value(False)
    print(str(type(myutil.get_class_value())))
    print(myutil.get_class_value())

これに対して

--- test-2 ---
<class 'bool'>
False

こうなっているのでこれもおかしな点は無し

test-3

問題はここから

    print("--- test-3 ---")
    print(str(type(myutil.get_class_value)))
    print(myutil.get_class_value)

メソッドを呼び出すのに()をつけないとどうなるか

--- test-3 ---
<class 'method'>
<bound method utilclass.get_class_value of <__main__.utilclass object at 0x785fe4d8a030>>

型はメソッドクラスでオブジェクト番号を参照しているように見える

https://docs.python.org/ja/3.13/tutorial/classes.html#method-objects
これによるとどうやらメソッドオブジェクトというオブジェクト扱いで値(参照というべきか?)が返ってくるようだ

ではこれがif分に渡されるとどうなるかというと次のテスト

test-4

    print("--- test-4 ---")
    if (myutil.get_class_value):
        print("Class Value is True")
    else:
        print("Calss Value is False")

booleanオブジェクトではないのでTrueやFalseは返してこないと思われる。
ただしboolean型は「整数のサブクラス」なので実際には0かそれ以外かだったような気はするけど資料が見つからず。
https://docs.python.org/ja/3.13/c-api/bool.html

Pythonのif文も"0かそれ以外か"だった気はするのだけれど詳しいことは書かれてなかった。
https://docs.python.org/ja/3.13/reference/compound_stmts.html#the-if-statement

さすがにソースコードまで追いかけるのはめんどかったのでこれを見た誰かがフォローアップ記事を書くかもしれないし書かないかもしれないくらいでお茶を濁しておく。

--- test-4 ---
Class Value is True

結果としては"True"側で判定されている。

何を判定しているかまではちょっとわからなかったが、もし"0かそれ以外か"だと仮定して、オブジェクトのばsy(今回は0x785fe4d8a030)を判定しているのだとすれば一応説明はつくかな、というところ

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?