Python でのカプセル化

Jan 21 2023
カプセル化という言葉を初めて聞くと、特に初心者の場合、プログラミングの世界では非常に派手で技術的で複雑な作業のように思えます。さまざまな情報源からカプセル化について学ぼうとしたとき、誰かが物語的な方法で理解しやすくしてくれたらいいのにと思いました。

カプセル化という言葉を初めて聞くと、特に初心者の場合、プログラミングの世界では非常に派手で技術的で複雑な作業のように思えます。さまざまな情報源からカプセル化について学ぼうとしたとき、誰かが物語的な方法で理解しやすくしてくれたらいいのにと思いました。したがって、ここでは、オンラインとオフラインの両方で大量の資料を読んだ後で理解したようにカプセル化を説明しようとしています。

  • ここではカプセル化について学びに来ているので、OOP (オブジェクト指向プログラミング) についてはすでにある程度の知識があると思います。

「カプセル化とは、データ (変数) とデータに作用するコード (メソッド) を 1 つの単位としてラップするメカニズムです。」

それ自体、かなり危険な定義のように思えます。簡単な方法で理解しましょう。

あなたがスタートアップの上級プログラマで、ユーザーがスタートアップのアプリケーションにアカウントを作成できるようにするメカニズムの構築を担当するチームがあると仮定します。現時点では、ユーザーの名前とパスワードのみを使用してアカウントを設定し、許可するパスワードは数字のみであるとします。はい!現実の世界では、パスワードを数字だけにするのは現実的ではないことはわかっていますが、このトピックを理解するために、それを仮定してみましょう。上級プログラマーであるあなたはアカウント クラスの作成を担当し、ジュニア プログラマーはそのクラスの使用を担当します。

次のようにクラスを作成したとします。

class Account:
    # constructor
    def __init__(self):
        self.user = ''
        self.password = 0
        self.menu()
    
    # display option
    def menu(self):
        user_input = input("""
        Select to Enter the following details:
        1. set account
        2. login
        5. Exit
        """)
        if user_input == '1':
            self.set_account()
        elif user_input == '2':
            self.login()
        else:
            exit()
    # To set account
    def set_account(self):
        user_name = input("set user id: ")
        self.user = user_name
        user_password = int(input("Set Password: "))
        self.password = user_password
    # To login
    def login(self):
        user_input = input("enter User id: ")
        if user_input == self.user:
            user_pass = int(input("enter password: "))
            if user_pass == self.password:
                return "Welcome {}".format(self.user)
            else:
                return "wrong password"
        else:
            return "user not found"

「 Rohit 」がユーザーで、次のコマンドを使用してアカウントを作成したとしましょう。

rohit = Account()

# after running the above code we get the prompt and add the following detail
"""
Select to Enter the following details:
        1. set account
        2. login
        5. Exit
        1
set user id: rohit
Set Password: 123
"""

rohit.password

このような状況に対処するために、カプセル化が私たちの仕事とユーザーのアイデンティティを救うスーパーヒーローとして登場します。

カプセル化が行うことは、変数をプライベートにすることができるということです。これが、variables(data) をラップすることを意味します。Python でそれを行うにはどうすればよいですか。プライベートにしたいデータのプレフィックスに二重アンダースコアを追加するだけです ( __data )。

ここで、 Account クラスの場合、ユーザーのパスワードを他の人に知られたくないです。したがって、コードを次のように変更します。

class Account:

    def __init__(self):
        self.user = ''
        self.__password = 0
        self.menu()
            
    def menu(self):
        user_input = input("""
        Select to Enter the following details:
        1. set account
        2. login
        5. Exit
        """)
        if user_input == '1':
            self.set_account()
        elif user_input == '2':
            self.login()
        else:
            exit()
    
    def set_account(self):
        user_name = input("set user id: ")
        self.user = user_name
        user_password = int(input("Set Password: "))
        self.__password = user_password
    
    def login(self):
        user_input = input("enter User id: ")
        if user_input == self.user:
            user_pass = int(input("enter password: "))
            if user_pass == self.__password:
                return "Welcome {}".format(self.user)
            else:
                return "wrong password"
        else:
            return "user not found"

ここで、誰かがパスワード変数にアクセスしようとすると、次のようなエラーがスローされます。

rohit.password

# running the above piece of code will output the following error
"""
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-7ddf6c297392> in <module>
----> 1 rohit.password

AttributeError: 'Account' object has no attribute 'password'
"""

rohit._Account__password

# Output 
# 1234

しかし、何もプライベートなものがないのに、なぜカプセル化という概念があるのでしょうか? それがあなたの心の中で起こっていることだと私は知っていますよね?つまり、重要な変数やメソッドを他の人 (若手プログラマーやユーザー) に知られたり、変更されたりしたくない場合には、カプセル化が必要になるということです。ソース コードにアクセスできるまでは、どの変数やメソッドがプライベートであるかを知ることができないため、それらにアクセスしたり変更したりすることはできません。

しかし、Rohit がパスワードを忘れて、パスワードを取得または変更したい場合はどうなるでしょうか。慣例として、 Getter メソッドとSetterメソッドとして知られるプライベート変数へのアクセスと変更を可能にする 2 つのメソッドをクラス内に作成します。これらはどうやって作るのですか?次のコードを使用します。

class Account:

    def __init__(self):
        self.user = ''
        self.__password = 0
        self.menu()
    
    # GETTER
    def get_pass(self):
        return self._Account__password
    # SETTER
    def set_pass(self,newpass):
        if type(newpass) == int:
            self.__password = newpass
        else: return "Password should only be numeric"
            
    def menu(self):
        user_input = input("""
        Select to Enter the following details:
        1. set account
        2. login
        5. Exit
        """)
        if user_input == '1':
            self.set_account()
        elif user_input == '2':
            self.login()
        else:
            exit()
    
    def set_account(self):
        user_name = input("set user id: ")
        self.user = user_name
        user_password = int(input("Set Password: "))
        self.__password = user_password
    
    def login(self):
        user_input = input("enter User id: ")
        if user_input == self.user:
            user_pass = int(input("enter password: "))
            if user_pass == self.__password:
                return "Welcome {}".format(self.user)
            else:
                return "wrong password"
        else:
            return "user not found

変数だけでなく、Python ではメソッドをプライベートにすることもできます。プロセスは同じですが、メソッド名を「 __method 」に変更するだけで、メソッドがプライベートになります。

プライベート変数の作成、ゲッター メソッドを使用したプライベート変数へのアクセス、およびセッター メソッドを使用したプライベート変数の値の変更という概念全体は、カプセル化として知られています。

このブログが何らかの形であなたのお役に立てれば幸いです。サインオフします!さようなら