Menu
Coddy logo textTech

アクセス修飾子

CoddyのPythonジャーニー「Object Oriented Programming」セクションの一部 — レッスン 29/64。

アクセス修飾子は、クラスの属性やメソッドの可視性を制御します。Pythonは、アクセス制御のためにキーワードではなく命名規則を使用します。

パブリックアクセスの例(プレフィックスなし)は以下の通りです:

class Person:
    def __init__(self):
        self.name = "Coddy"      # パブリック属性
        
    def greet(self):             # パブリックメソッド
        return f"Hello, I'm {self.name}"

どこからでもパブリックメンバにアクセスできます:

person = Person()
print(person.name)           # Coddy
print(person.greet())        # こんにちは、私はCoddyです

保護されたアクセス(アンダースコア1つ)の例を以下に示します:

class Employee:
    def __init__(self):
        self._salary = 50000     # 保護された属性
    
    def _calculate_bonus(self):  # 保護されたメソッド
        return self._salary * 0.1

    def show_bonus(self):
        return self._calculate_bonus()  # クラス内での使用はOK

保護されたメンバーへのアクセス(動作はしますが、推奨されません):

employee = Employee()
print(employee._salary)      # 50000 - 動作はしますが、非推奨です
print(employee.show_bonus()) # 5000.0 - 適切な方法

以下は、プライベートアクセス(アンダースコア2つ)の例です:

class User:
    def __init__(self):
        self.__password = "secure123"   # プライベート属性
        
    def __encrypt(self, data):          # プライベートメソッド
        return f"Encrypted: {data}"
        
    def verify(self, input_password):
        # クラス内部からアクセス可能なプライベートメンバ
        return input_password == self.__password

プライベートメンバを正しく使用してください:

user = User()
print(user.verify("secure123"))  # True - 公開メソッドを使用
# print(user.__password)         # AttributeError - 直接アクセスできません

出力:

Coddy
Hello, I'm Coddy
50000
5000.0
True

重要なポイント: Pythonのアクセス修飾子は命名規則です。プレフィックスなし = public(どこからでもアクセス可能)、アンダースコア1つ = protected(内部利用)、アンダースコア2つ = private(クラス内のみ)。これらは明確な境界を確立し、クラス内部の誤用を防ぐのに役立ちます。

challenge icon

チャレンジ

中級

このチャレンジでは、包括的なテストの利点を体験しながら、Pythonのアクセス修飾子(public、protected、private)を実演する FileManager クラスを実装します。

TODO コメントに従って FileManager クラスを実装するために、filemanager.py を編集してください。このファイルには、以下の実装に関する詳細な指示が含まれています:

  • ファイル操作のためのパブリックメソッド
  • プロテクテッドメソッド(アンダースコア1つの接頭辞付き)
  • プライベートメソッド(アンダースコア2つの接頭辞付き)
  • カプセル化を示すメソッド間の相互作用

チートシート

Pythonはアクセス制御に命名規則を使用します:

パブリックアクセス (プレフィックスなし) - どこからでもアクセス可能:

class Person:
    def __init__(self):
        self.name = "Coddy"      # パブリック属性
        
    def greet(self):             # パブリックメソッド
        return f"Hello, I'm {self.name}"

person = Person()
print(person.name)           # Coddy
print(person.greet())        # Hello, I'm Coddy

保護されたアクセス (アンダースコア1つ) - 内部用、外部からの使用は非推奨:

class Employee:
    def __init__(self):
        self._salary = 50000     # 保護された属性
    
    def _calculate_bonus(self):  # 保護されたメソッド
        return self._salary * 0.1

employee = Employee()
print(employee._salary)      # 動作しますが非推奨です

プライベートアクセス (アンダースコア2つ) - クラス内のみ:

class User:
    def __init__(self):
        self.__password = "secure123"   # プライベート属性
        
    def __encrypt(self, data):          # プライベートメソッド
        return f"Encrypted: {data}"
        
    def verify(self, input_password):
        return input_password == self.__password

user = User()
print(user.verify("secure123"))  # True - パブリックメソッドを使用
# print(user.__password)         # AttributeError - 直接アクセスできません

自分で試してみよう

from file_manager import FileManager

# 包括的なテストケースハンドラー
test_case = input()

if test_case == "basic_test":
    # FileManagerのインスタンスを作成
    manager = FileManager()
    # read_fileメソッドを呼び出す
    print(manager.read_file("example.txt"))
    # get_file_contentメソッドを呼び出す
    print(manager.get_file_content("example.txt"))

elif test_case == "protected_access":
    # FileManagerのインスタンスを作成
    manager = FileManager()
    # 保護されたメソッドの呼び出しを試行
    # 保護されたメソッドはアクセス可能だが、内部利用を目的としている
    print(manager._check_permissions("example.txt"))
    print("Note: Protected methods are accessible but intended for internal use only")

elif test_case == "private_access":
    # FileManagerのインスタンスを作成
    manager = FileManager()
    try:
        # プライベートメソッドを直接呼び出そうとする
        print(manager.__decrypt_content("some content"))
    except AttributeError as e:
        print(f"Error: {e}")
        print("Private methods are name-mangled and cannot be accessed directly")
    
    # 名前修飾(name-mangled)された形式を使用してアクセス
    print(manager._FileManager__decrypt_content("some content"))
    print("Note: Accessed private method using name-mangled form")

elif test_case == "method_chaining":
    # FileManagerのインスタンスを作成
    manager = FileManager()
    # get_file_contentが内部で保護されたメソッドとプライベートメソッドの両方を呼び出す様子を示す
    print("Calling get_file_content which internally uses protected and private methods:")
    print(manager.get_file_content("example.txt"))

elif test_case == "multiple_files":
    # FileManagerのインスタンスを作成
    manager = FileManager()
    # 複数のファイルを処理
    files = ["document.txt", "image.jpg", "data.csv"]
    
    for file in files:
        print(f"\
Processing {file}:")
        print(manager.read_file(file))
        print(manager.get_file_content(file))

elif test_case == "name_mangling":
    # FileManagerのインスタンスを作成
    manager = FileManager()
    # 名前修飾(name mangling)の実演
    print("Python's name mangling for private methods:")
    print("Attempting direct access would fail with AttributeError")
    print("Using mangled name:")
    print(manager._FileManager__decrypt_content("private data"))
    print("\
Name mangling is Python's mechanism to prevent accidental access")
    print("It renames __method to _ClassName__method internally")
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Object Oriented Programmingのすべてのレッスン