【Python入門】初めてのプログラミング(アクセス制御)

※このサイトの記事内では広告を掲載している場合があります。

こんにちわ!この記事はPythonの初学者のための内容となっております。
今回はアクセス制御についての内容です。カプセル化とも言いますが、Pythonではアクセス制御のほうが意味が近いでしょう。

  • アクセス制御って何!?
  • 関数の前についてる「 _ 」の意味が分からない

という方向けの内容です。

また、変数の有効範囲であるスコープも関連しているので参考にどうぞ!

それでは頑張っていこう!

プログラミングスクールに関しては下の記事で詳しく記述しています。

こちらで紹介しているスクールは、すべて無料期間がある優良なスクールのみで、特徴を明確にし、読者のニーズに絞って丁寧に解説しました。初めての一歩として、無料説明会に参加してみてください。

アクセス制御について

アクセス制御とは

メソッド(関数)や変数に対する、外部からのアクセスを制御することです。

Pythonでは、「private」や「protected」、「public」などの、ほかのプログラミング言語ではサポートされていることの多いアクセス修飾子はありません。その代わりに、「 _ 」:アンダーバーを用いて、アクセスの制御を行います。

アクセス制御を用いると便利な場面

  • 参照する必要のない変数は、最初からアクセスできないようにする
    →エラーをあえて出し、今後のミスを未然に防ぐ
  • 複数のプログラマが関わるとき、知るべきでない情報を参照できないようにする
    →セキュリティー対策やプログラムを組むうえで簡素化につながる

まあ、ほかにもいろいろメリットはあるでしょうが、プログラムが膨大になってくるほど、今回学ぶアクセス制御が役に立ちます。実際に記述例を見ていきましょう!

アクセス制御の記述例

個人情報のアクセス制御

アクセス制御を行うことで、クラスの外から変数や関数を参照することが出来なくなります。メンバ変数「adress」(住所)は、外部の人に簡単に知られてはいけないので、今回は関数「getAdress」にアクセス制御を設けました。


class Person:
    def __init__(self, name, adress):
        self.name = name
        self.__adress = adress

    def getName(self):
        return self.name

    def introduce(self):
        print(self.name + "さんの住所は" + self.__getAdress() + "です。")

    def __getAdress(self):
        return self.__adress


if __name__ == "__main__":
    p = Person("パンドラ", "宮城県宮城郡七ヶ浜町○○-○○")
    print(p.getName())
    #パンドラ

    p.introduce()
    #パンドラさんの住所は宮城県宮城郡七ヶ浜町○○-○○です。

    p.getAdress()
    #AttributeError

    p.__getAdress()
    #AttributeError

「関数「introduce」があるから意味ないやん!」と思う方もいるかもしれませんが、複数人でプログラムを組んでいて、関数名を知らなかった場合、「adress」にアクセスすることが出来ないのでセキュリティー対策になります。

カード番号のアクセス制御と暗号化

例えば、銀行システムなどの場合、キャッシュカードを入れてからカード番号の確認をするなど、処理フローが明確な場合は、前のフローが終了してから次の関数を呼び出すなどできるので、アクセス制御を設ければ、ミスを未然に防ぐことが可能です。


class Card:
    def __init__(self, type, number):
        self.type = type
        self.__number = number.split("-")
        self.__acceptance()

    def __acceptance(self):
        card_type = ["Visa", "JCB"]

        if self.__getType() in card_type:
            print("カードを受け取りました。カード番号を暗号化します。")
            self.__encryption(int(self.__getNumber()[0][0]))
        else:
            return 0

    def __encryption(self, num):
        ans = []

        for n in self.__getNumber():
            temp = [str((int(i) + num) % 10) for i in n]
            ans.append("".join(temp))
        
        self.__number = ans
        print(self.__number)
        #self.__decryption(num):復号化。本日の問題で使用。
        
    def __decryption(self, num):
        print("復号化をします。")
        ans = []

        for n in self.__getNumber():
            temp = [str((int(i) - num) % 10) for i in n]
            ans.append("".join(temp))
        
        self.__number = ans
        print(self.__number) 
    
    def __getType(self):
        return self.type

    def __getNumber(self):
        return self.__number


if __name__ == "__main__":
    card1 = Card("Visa", "1234-5678-9012-3456")
    card2 = Card("JCB",  "5286-5236-1232-8765")

"""
カードを受け取りました。カード番号を暗号化します。
['2345', '6789', '0123', '4567']
カードを受け取りました。カード番号を暗号化します。
['0731', '0781', '6787', '3210']
"""

コードについて順番に解説していくよ!

今回は、カードのインスタンスを生成した時に、コンストラクタの中で関数「acceptance」を呼び出すようにしました。普通はこんなことしないのかもしれませんが、自分は学生で実務経験はないので許してください笑。

クラス「Card」のインスタンスが生成されたとき、自動的にカードを認識する流れがあるので、関数「acceptance」には、アクセス制御を設けています。逆に、カードが認識されてもいないのに、この関数が呼び出されるようなことがあってはいけないからですね。

関数「acceptance」を実行すると、次は、カード番号を暗号化する関数「encryption」が出てきます。この関数の引数は、カード番号の一番最初の数字の数だけ各桁に足して10で割ったあまりを暗号文としています。オブジェクト「card1」の最初の数字は「1」となっているので、カード番号のすべての数字が「1」足されたものになっていますね。

暗号化はこんなに単純ではないですが、今回は例なので気にしないでください。カード番号に関しても、ほかのクラスや関数で参照されてはいけないのでこちらもアクセス制御を付けています。

オブジェクト指向の具体的な使い方を、今回のプログラムに似たコードを用いて記述しているのでそちらを見ていただければより理解が深まると思います。

まとめ

今回は、アクセス制御についての記述でした。アクセス制御を設けることで、ほかのクラスや関数から参照することを制御することが出来ます。ただ、Pythonでは、完全にほかのクラスからの参照を制御することは出来ないようです。

アクセス制御の便利な使い方としては、処理のフローを考えた時に、関数の異常な呼び出しを避けるために利用することも可能です。今回の例では、超簡易版銀行システムのカード番号の暗号化では、カードが認識される前に暗号化されるというのはそもそも現実では起こりえないことですよね。こういった流れがある場合にもアクセス制御は有効的でした。

本日の理解度調査

今日の最後に理解度調査をします!!
どうすれば正しくなるのか考えてみてね!!

Q. 番号を復号化(暗号化されたものを平文に戻す)する関数「__decryption」を完成させよ。


def __decryption(self, num):
    print("復号化をします。")
    ans = []

    for n in self.__getNumber():
        temp = [???]
        ans.append("".join(temp))
        
    self.__number = ans
    print(self.__number)    

正解は。。。

temp = [str((int(i) - num) % 10) for i in n]

わかったかな??正解出来たら今回の項目は完璧だね!!

最後まで記事を読んでいただきありがとうございます!

昔、自分が参考にしていたプログラミングについての書籍を紹介します。
非常にわかりやすい内容ですのでぜひとも参考にしてみてください!

プログラミングスクールに関しては下の記事で詳しく記述しています。

こちらで紹介しているスクールは、すべて無料期間がある優良なスクールのみで、特徴を明確にし、読者のニーズに絞って丁寧に解説しました。初めての一歩として、無料説明会に参加してみてください。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA