57688


Pythonのクラスについてお聞きしたいのですが、クラス内のdefは上から順番に読み込まれていくのではないのでしょうか？  
以下のようなプログラムがあります。

[code]

    class API(Person):
        def __init__(self, FBtoken):
            # Facebookのトークンを元に、tinderのトークンを取得します。
            params = {"token": FBtoken}
            with requests.Session() as s:
                headers = {
                    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"}
                s.headers.update(headers)
                response = s.post(
                    "https://api.gotinder.com/v2/auth/login/facebook", data=json.dumps(params))
                if response.status_code == 401:  # 予期せぬトラブル
                    sys.exit(1)
                data = json.loads(response.text)["data"]
                self.id = data["_id"]
                self.api_token = data["api_token"]
                self.refresh_token = data["refresh_token"]
    
            # Tinderのサーバーにリクエストするためのヘッダー。
            self.header = {"X-Auth-Token": self.api_token, "Content-type": "application/json",
                           "User-agent": "Tinder/10.1.0 (iPhone; iOS 12.1; Scale/2.00)"}
    
            # 自分の情報を取得します。
            meta = self.getMeta()
    
            # Personクラスを継承
            super().__init__(meta["user"])
    
            self.age_filter_max = meta["user"]["age_filter_max"]
            self.age_filter_min = meta["user"]["age_filter_min"]
            self.distance_filter = meta["user"]["distance_filter"]
            self.gender_filter = meta["user"]["gender_filter"]
            self.full_name = meta["user"]["full_name"]
    
        # 自分の情報を取得
        def getMeta(self):
            endpoint = "meta"
            return self._request(endpoint)
    
        # 残り右スワイプ数
        def getLikesRemaining(self):
            return int(self.getMeta()["rating"]["likes_remaining"])
    
[/code]

このプログラムではgetMeta関数が記述されている位置よりも上にあるのですが、通常の関数のみですと関数を実行するよりも上に関数を記述していないとエラーが出ると思うのですが、クラスではそれが起きないのでしょうか？

あともう一つ気になるのが`Class API（Person）：`と記述されており、これよりも上にPersonクラスが記述されています。  
そしてこのクラスを利用する際、このような書き方がされています。`api =
tinpy.API（token)`この書き方でもPersonは継承されるのでしょうか？個人的なイメージでtokenに上書きされそうな気もします。ちなみにtokenにはFacebookのアクセストークンが入る予定です。

全体のコードは以下のGithubにあり、クラスを理解するために読んでいます。  
<https://github.com/FullteaOfEEIC/tinpy2>


CC BY-SA 4.0
2019-08-29T05:29:33.823
57686
2019-08-29T13:06:44.897
22565
question
python python3
PythonのClassの実行する順番について


# メソッド(関数)の中でまだ定義されていないメソッド(関数)が使える理由

python
は、メソッドの定義の段階では、そのメソッドは実行されず、実際にメソッドが定義されていない類のエラーで発生するのは、実際にそのメソッドを実行するタイミングになってからだからです。

例えば、以下のようなコードを実行したとすると、問題なく実行できます。

[code]

    def foo():
        bar()
    
    def bar():
        print("bar")
    
    foo()
    # => bar
    
[/code]

一方、以下はエラーになります。

[code]

    def foo():
        bar()
    
    foo()
    
    def bar():
        print("bar")
    
[/code]

エラーメッセージ

[code]

    Traceback (most recent call last):
      File "test2.py", line 5, in <module>
        foo()
      File "test2.py", line 3, in foo
        bar()
    NameError: global name 'bar' is not defined
    
[/code]

# Person が継承できている理由

  1. `class API(Person):` によって親クラスが宣言されていて、
  2. `super().__init__(meta["user"])` によってイニシャライザが呼ばれているので、正しく実装すれば、 Person のサブクラスとして正常に振る舞うことが期待できます。

* * *

(追記)

python では、クラスの `__init__` メソッドは、「オブジェクトを作成する際」に実行されます。

[code]

    class Foo:
        def __init__(self):
            print("In init")
    
    print("before new")
    Foo()
    print("after new")
    
    # before new
    # In init
    # after new
    
[/code]

なので、 `__init__`
メソッドの中で他のメソッドを実行していても、それが実行されるのは、クラス定義が終わって、それを実際にオブジェクトとしてインスタンス化する際になるので、その
`__init__` の中で、まだ `__init__` 定義時には定義されていない他のメソッドを読んでいたとしても、問題は発生しません。


CC BY-SA 4.0
2019-08-29T06:10:28.913
57688
2019-08-29T13:06:44.897
2019-08-29T13:06:44.897
754
754
57686
answer