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

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

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

## サンプルコード

```python
# 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

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

これに対して

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

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

### test-2

```python
    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

問題はここから

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

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

### test-4

```python
    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](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](https://docs.python.org/ja/3.13/reference/compound_stmts.html#the-if-statement)

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

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

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

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