class内での「self.変数」と「変数」の違いについて


djangoのDetailViewをつかわずその機能が書かれた以下のコードがありました。

[code]

    class TopicTemplateView_InsteadOfDetailView(TemplateView):
        template_name = 'thread/detail_topic.html'
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['topic'] = get_object_or_404(Topic, id=self.kwargs.get('pk', ''))
    
            return context
    
[/code]

気になったラインが一行あって、

[code]

        context['topic'] = get_object_or_404(Topic, id=self.kwargs.get('pk', ''))
    
[/code]

このラインは,selfがついていてなぜセルフが必要なのか、絶対必要なのかと思い、selfなしをプリントしてみたところ、どちらも同じ結果を返しました。  
(pkの値を位置を与えたときは、どちらも1が返ってきた。）

[code]

        print(kwargs.get('pk',''))      # 1 
        print(self.kwargs.get('pk','')) # 1
    
[/code]

self.kwargs, kwargs ともにdictオブジェクトでした。

クラス内では、変数宣言するときに `self.変数 = 値` としますが、`変数 = 値` とでは何が違うのでしょうか？




インスタンス変数self.kwargsはsetupメソッドの中で[作成されていて](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L87)、setupはas_viewメソッドが返す[関数の中で呼ばれます](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L65)。  
アクセスがあると、[dispatch](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L89)されて、[getattr](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L94)で探し出されて、[TemplateViewのget](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L157)が呼び出されます。

TemplateViewのgetは

[code]

        def get(self, request, *args, **kwargs):
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)
    
[/code]

こうです。

ここでget_context_dataが呼び出されて、質問のget_context_dataが実行されるので、その時点でkwargsとself.kwargsはオブジェクトとして等しいものを指していると思います。  
（実行して確認はしてません。悪しからず）

私は"self.kwargsとする方が紛らわしい"という感想を持ちました。




インスタンス変数self.kwargsはsetupメソッドの中で[作成されていて](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L87)、setupはas_viewメソッドが返す[関数の中で呼ばれます](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L65)。  
アクセスがあると、[dispatch](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L89)されて、[getattr](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L94)で探し出されて、[TemplateViewのget](https://github.com/django/django/blob/3.0.5/django/views/generic/base.py#L157)が呼び出されます。

TemplateViewのgetは

[code]

        def get(self, request, *args, **kwargs):
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)
    
[/code]

こうです。

ここでget_context_dataが呼び出されて、質問のget_context_dataが実行されるので、その時点でkwargsとself.kwargsはオブジェクトとして等しいものを指していると思います。  
（実行して確認はしてません。悪しからず）

私は"self.kwargsとする方が紛らわしい"という感想を持ちました。

