Public and Private Attributes and Methods in Python


In Python, attributes and methods of a class can be categorized as public or private. This categorization determines their accessibility and usage. Public members are accessible from anywhere, while private members are meant to be accessed only within the class. This article explains these concepts with examples.

Public Attributes and Methods

Public attributes and methods are accessible from anywhere in the code, including outside the class. By default, all attributes and methods in Python are public unless explicitly made private.

Example 1: Public Attributes

    class Person:
        def __init__(self, name, age):
            self.name = name  # Public attribute
            self.age = age    # Public attribute

    person = Person("Alice", 30)
    print(f"Name: {person.name}, Age: {person.age}")
        

In this example, name and age are public attributes and can be accessed directly using the object.

Example 2: Public Methods

    class Calculator:
        def add(self, a, b):
            return a + b

        def subtract(self, a, b):
            return a - b

    calc = Calculator()
    print(f"Addition: {calc.add(10, 5)}")
    print(f"Subtraction: {calc.subtract(10, 5)}")
        

Here, the add and subtract methods are public and can be called directly using the object.

Private Attributes and Methods

Private attributes and methods are intended to be used only within the class. They are created by prefixing their names with double underscores (__). Although Python does not enforce strict access control, private members are name-mangled to prevent direct access.

Example 3: Private Attributes

    class BankAccount:
        def __init__(self, account_number, balance):
            self.__account_number = account_number  # Private attribute
            self.__balance = balance                # Private attribute

        def get_balance(self):
            return self.__balance

    account = BankAccount("12345", 1000)
    # print(account.__balance)  # Raises AttributeError
    print(f"Balance: {account.get_balance()}")
        

In this example, __account_number and __balance are private attributes. They cannot be accessed directly outside the class, but their values can be retrieved using the get_balance method.

Example 4: Private Methods

    class Robot:
        def __init__(self, name):
            self.name = name

        def __secret_code(self):
            return "1234"

        def reveal_secret(self):
            return f"The secret code is {self.__secret_code()}."

    robot = Robot("Robo")
    # print(robot.__secret_code())  # Raises AttributeError
    print(robot.reveal_secret())
        

Here, __secret_code is a private method that cannot be accessed directly. However, it can be called indirectly through the public method reveal_secret.

Accessing Private Members

Python uses name mangling for private members, which means their names are internally changed to include the class name. This can still allow access, but it is not recommended as it violates the principle of encapsulation.

Example 5: Name Mangling

    class Example:
        def __init__(self):
            self.__private_var = "Private"

    example = Example()
    print(example._Example__private_var)  # Accessing private variable using name mangling
        

In this example, the private variable __private_var is accessed using its mangled name. This is not a recommended practice.

Comparison of Public and Private Members

  • Public: Accessible from anywhere in the code.
  • Private: Accessible only within the class. Can be accessed outside the class using name mangling, but it is discouraged.

Best Practices

  • Use public attributes and methods for data and behaviors meant to be accessed from outside the class.
  • Use private attributes and methods to encapsulate sensitive data and internal logic.
  • Provide public getter and setter methods to access or modify private attributes safely.

Example 6: Getter and Setter Methods

    class Employee:
        def __init__(self, name, salary):
            self.name = name
            self.__salary = salary  # Private attribute

        def get_salary(self):
            return self.__salary

        def set_salary(self, amount):
            if amount > 0:
                self.__salary = amount
            else:
                print("Invalid salary amount")

    employee = Employee("John", 5000)
    print(f"Salary: {employee.get_salary()}")
    employee.set_salary(6000)
    print(f"Updated Salary: {employee.get_salary()}")
        

This example demonstrates how getter and setter methods provide controlled access to a private attribute.

Conclusion

Public and private attributes and methods allow for better control and encapsulation in object-oriented programming. Public members are accessible from anywhere, while private members are restricted to the class. Using getter and setter methods is a common way to manage private attributes effectively.





Advertisement