curso
Explicação dos métodos privados do Python
Na programação orientada a objetos (OOP), uma abordagem de design de software, usamos "objetos" para modelar entidades do mundo real. Um objeto é uma estrutura de dados com atributos (dados) e métodos (funções) que atuam sobre os dados. Os sistemas complexos podem ser mais fáceis de projetar com objetos.
Saiba mais sobre os fundamentos e os conceitos de engenharia de software por trás da OOP iniciando nossocurso de programação orientada a objetos com Python.
O encapsulamento é um conceito fundamental na OOP. Isso significa agrupar os dados e os métodos de um objeto e ocultar os detalhes do mundo externo. Pense no encapsulamento como um processo que cria uma "cápsula" (um objeto) com seus próprios dados e maneiras de manipulá-los.
O principal objetivo do encapsulamento é:
- Impedir o acesso direto aos dados (integridade dos dados).
- Simplifique o sistema mostrando apenas o que é necessário (abstração).
Os métodos privados são fundamentais para que você consiga esse encapsulamento, ocultando os detalhes internos de implementação de uma classe.
Ao tornar um método privado, você informa a outros programadores que esse método não deve ser acessado diretamente. Isso pode evitar bugs e erros, garantindo que o estado interno de um objeto só possa ser alterado de forma controlada.
Aqui, apresentaremos os métodos privados, a sintaxe para defini-los, a implementação de métodos privados em exemplos do mundo real e as práticas recomendadas para usá-los.
O que são métodos privados?
Os métodos privados na programação orientada a objetos (OOP) são funções dentro de uma classe projetada apenas para uso interno. Eles encapsulam a funcionalidade de uma classe, garantindo que seu funcionamento interno permaneça protegido da interação externa.
Esse encapsulamento fornece uma camada de abstração, permitindo que a classe mantenha o controle sobre seu estado e comportamento internos e altere sua implementação sem afetar o código externo que depende dela.
Em Python, a convenção para indicar métodos privados é prefixar o nome do método com um único sublinhado (_) ou dois sublinhados (__). Isso serve como uma dica para os desenvolvedores sobre o escopo pretendido do método e é apenas uma convenção.
Embora essa convenção não imponha uma privacidade rigorosa como em outras linguagens, é uma prática respeitada na comunidade Python para sinalizar o uso pretendido do método. Mais tarde, vamos nos aprofundar nesses aspectos de forma mais abrangente.
A sintaxe dos métodos privados
Há duas maneiras diferentes de definir métodos privados, que veremos por meio de exemplos.
Podemos definir um método privado usando um único sublinhado antes do nome da função:
class MyClass:
def _private_method(self):
print("This is a private method")
Essa definição é apenas uma convenção para os programadores, pois a função ainda pode ser acessada fora da classe, embora isso não seja recomendado.
Se esta é a primeira vez que você ouve falar de classes em Python, recomendamos que confira primeiro nosso tutorial para iniciantes sobre Classes.
Vamos criar um objeto e tentar acessar o método privado criado:
# Creating an object
obj = MyClass()
# Accessing from outside
obj._private_method() # Not recommended to call directly, but possible
Há outra sintaxe para definir métodos privados em Python usando sublinhados duplos. A aparência é a seguinte: :
class MyClass:
def __private_method(self):
print("This is a private method")
obj = MyClass()
# obj.__private_method() # This will raise an AttributeError
Quando tentamos acessar o método privado de fora da classe, ele gera um AttributeError, indicando que não pode ser acessado diretamente usando o nome da função.
Para resumir a sintaxe de métodos privados em Python, você deve usar a sintaxe de métodos privados:
- Sublinhado simples: apenas uma convenção para os programadores, pode ser acessado fora da função.
- Sublinhado duplo: não pode ser acessado fora da função apenas com o nome da função. Ele ainda pode ser acessado por meio do "Name Mangling", que veremos mais adiante neste tutorial.
Implementação de métodos privados em Python
Como exemplo do mundo real, considere uma classe BankAccount segura e fácil de usar para gerenciar as transações financeiras de um usuário. Os requisitos das contas bancárias são:
- A classe deve encapsular o saldo do titular da conta, permitindo depósitos e retiradas e garantindo que o saldo não possa ser manipulado diretamente fora da classe.
- A classe deve facilitar transferências seguras entre contas, atualizando o saldo da conta do destinatário sem expor o mecanismo interno de modificação do saldo.
- A solução deve aderir aos princípios da programação orientada a objetos, especificamente encapsulamento e abstração, para manter a integridade dos dados da conta e fornecer uma interface clara e simples para interagir com a conta.
É claro que uma conta bancária precisa de mais funcionalidades, como verificação de saldo, conversão de moeda e tratamento de juros, mas, para simplificar, vamos ignorá-las em nossa implementação.
Vamos implementar essa solução e entender o código.
class BankAccount:
def __init__(self, account_holder, initial_balance=0):
self.account_holder = account_holder
self.__balance = initial_balance # Private attribute
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"Deposited ${amount}. New balance: ${self.__balance}")
else:
print("Deposit amount must be positive.")
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
print(f"Withdrew ${amount}. New balance: ${self.__balance}")
else:
print("Insufficient funds or invalid amount.")
def __update_balance(self, amount): # Private method
self.__balance += amount
def transfer(self, amount, other_account):
if 0 < amount <= self.__balance:
self.withdraw(amount)
other_account.__update_balance(amount)
print(f"Transferred ${amount} to {other_account.account_holder}.")
else:
print("Insufficient funds or invalid amount.")
Primeiro, criamos um objeto BankAccountclass
, que envolve todos os comportamentos e funcionalidades pretendidos exigidos por um objeto BankAccount.
A classe BankAccount
tem um atributo privado __balance
e um método privado __update_balance
:
- Variável privada (
__balance
): Esse é um atributo da classeBankAccount
que armazena o saldo da conta corrente. Ele é marcado como privado ao prefixar seu nome com dois sublinhados (__
). Isso significa que ele deve ser acessado somente dentro da própria classe. Por exemplo, ele é modificado pelos métodos deposit,withdraw
e__update_balance
. O acesso externo a esse atributo não é recomendado. - Método privado (
__update_balance
): O objetivo desse método é atualizar o saldo da conta. Ele é chamado pelo métodotransfer
para atualizar o saldo da conta do destinatário durante uma operação de transferência. O uso de um método privado aqui ajuda a encapsular a lógica de atualização do saldo, garantindo que isso só possa ser feito de maneiras controladas definidas pela classe.
Sinta-se à vontade para criar um novo arquivo Python, copiar e colar o código acima e abaixo e executá-lo para ver você mesmo.
# Using the Bank Account Solution
account1 = BankAccount("John Doe", 1000)
account2 = BankAccount("Jane Doe", 500)
account1.deposit(200)
account1.withdraw(100)
account1.transfer(300, account2)
Você verá o resultado abaixo:
Deposited $200. New balance: $1200
Withdrew $100. New balance: $1100
Withdrew $300. New balance: $800
Transferred $300 to Jane Doe.
Parabéns a você! Você criou sua solução BankAccount usando um método privado!
Com base no resultado, vemos que, ao realizar as operações bancárias usuais, como depósito, retirada e transferência de fundos, o comportamento lógico usual de uma conta bancária é seguido.
O método __init__: ele é um método privado?
Você provavelmente notou o método __init__
usado no exemplo da conta bancária. Como ele também usa a sintaxe de dois sublinhados, você pode se perguntar se ele também é um método privado.
O método __init__
não é considerado um método privado da mesma forma que os métodos prefixados com dois sublinhados para privacidade.
Em vez disso, ele faz parte de métodos especiais em Python, geralmente chamados de método "dunder" (abreviação de "double underscore"), que tem uma finalidade específica na linguagem. Outros exemplos desses métodos especiais incluem __str__
, __repr__
e __del__
.
Vamos entender como esse método especial foi utilizado em nosso exemplo:
class BankAccount:
def __init__(self, account_holder, initial_balance=0):
self.account_holder = account_holder
self.__balance = initial_balance
Como você pode ver, o método __init__
é o construtor de uma classe. Ele é chamado automaticamente quando uma nova instância da classe é criada e é usado para inicializar os atributos do objeto. Para a classe BankAccount
, o método __init__
é usado para definir os valores iniciais dos atributos account_holder
e __balance
.
Conceitos avançados: Manipulação de nomes em Python
Anteriormente em nossa definição, mencionamos que os métodos privados em Python são apenas uma convenção, e a linguagem Python não impõe estritamente a privacidade, ao contrário de outras linguagens de programação.
Com razão, vimos que os métodos privados podiam ser acessados diretamente quando se usava um único sublinhado, mas o acesso era restrito quando se usava um sublinhado duplo.
Mas por quê? Por causa de um conceito chamado "name mangling" em Python.
Quando você prefixa um nome de atributo com dois sublinhados, o Python modifica automaticamente o nome adicionando um único sublinhado e o nome da classe antes do nome do atributo original.
Esse nome modificado é a forma como o atributo é armazenado internamente na classe. O processo de modificação do nome dessa forma é conhecido como "name mangling".
A mistura de nomes é útil por dois motivos:
- Prevenção de conflitos de nomes: Na herança, se uma subclasse definir um atributo com o mesmo nome de um atributo em sua superclasse, os dois entrarão em conflito. A manipulação de nomes ajuda a evitar esse problema, garantindo que os nomes sejam exclusivos para cada classe.
- Um grau de privacidade: Embora o Python não tenha atributos privados verdadeiros, a manipulação de nomes oferece uma maneira de tornar os atributos menos acessíveis de fora da classe, oferecendo assim um grau de privacidade.
Vamos ver um exemplo para você entender melhor.
class MyClass:
def __init__(self):
self.__private_attribute = "I am private"
def __private_method(self):
print("This is a private method")
obj = MyClass()
print(obj.__private_attribute) # This will raise an AttributeError
Neste exemplo, __private_attribute
e __private_method
são nomes misturados. Internamente, eles são armazenados como _MyClass__private_attribute
e _MyClass__private_method
, respectivamente. Se você tentar acessá-los usando seus nomes originais de fora da classe, isso resultará em um AttributeError
.
No entanto, você ainda pode acessá-los usando seus nomes adulterados:
print(obj._MyClass__private_attribute) # This will print "I am private"
obj._MyClass__private_method() # This will print "This is a private method"
Embora a alteração de nomes torne os atributos menos acessíveis, é importante observar que essa não é uma maneira infalível de garantir a privacidade no Python. É mais uma convenção para indicar que um atributo é destinado ao uso interno da classe.
Práticas recomendadas para o uso de métodos e variáveis privados
O aproveitamento eficaz de métodos e variáveis privados requer a adesão a determinadas práticas recomendadas. Essas práticas ajudam a garantir que seu código não seja apenas funcional, mas também claro, passível de manutenção e seguro.
Aqui estão algumas práticas recomendadas que você deve seguir:
- Use um único sublinhado para atributos "Protegidos". Se você quiser indicar que um atributo ou método deve ser usado na classe e em suas subclasses, mas não para uso externo, coloque um único sublinhado (
_
) como prefixo. Essa é uma convenção em Python que sinaliza para outros desenvolvedores que o atributo ou método é "protegido" e não deve ser acessado diretamente. - Use sublinhado duplo para atributos "Privados". Se você quiser tornar um atributo ou método menos acessível fora da classe para evitar modificações ou usos acidentais, prefixe-o com um sublinhado duplo (
__
). Isso aciona a manipulação de nomes e torna mais difícil (mas não impossível) acessar o atributo ou método de fora da classe. - Use métodos privados para a lógica interna. Os métodos privados (aqueles com um prefixo de sublinhado simples ou duplo) são uma ótima maneira de encapsular a lógica interna da sua classe. Use-os para executar tarefas específicas da implementação da classe e que não devem ser expostas como parte da interface pública da classe.
Por fim, é importante que você seja consistente com as práticas recomendadas de codificação. Atenha-se às convenções de nomenclatura e use-as de forma consistente em toda a sua base de código. Isso torna seu código mais fácil de entender e manter para outros desenvolvedores e para você mesmo no futuro.
Conclusão
Este tutorial apresentou a você os conceitos por trás dos métodos privados, sua sintaxe e quando você pode usá-los. Também vimos vários exemplos que ilustram como você pode usá-los em seu próximo projeto de codificação. Por fim, analisamos algumas práticas recomendadas que você deve ter em mente ao usá-las.
Para aprender mais, você pode conferir o curso Python Programming Skill Track e o curso Object-oriented Programming in Python.

Como cientista de dados sênior, eu projeto, desenvolvo e implanto soluções de aprendizado de máquina em larga escala para ajudar as empresas a tomar melhores decisões baseadas em dados. Como redator de ciência de dados, compartilho aprendizados, conselhos de carreira e tutoriais práticos e detalhados.
Continue sua jornada de aprendizado de Python!
curso
Programação orientada a objetos em Python
curso
Privacidade de dados e anonimização em Python

blog
6 práticas recomendadas de Python para um código melhor
tutorial
Tutorial e exemplos de funções e métodos de lista do Python
tutorial
Tutorial de docstrings em Python
tutorial
Como comentar um bloco de código em Python
tutorial
Como aparar uma cadeia de caracteres em Python: Três métodos diferentes
tutorial
Exponentes em Python: Um guia abrangente para iniciantes

Satyam Tripathi
9 min