Objetos são abstrações computacionais que representam entidades, com suas qualidades (atributos) e ações (métodos) que estas podem realizar. A classe é a estrutura básica do paradigma de orientação a objetos, que representa o tipo do objeto, um modelo a partir do qual os objetos serão criados.
Por exemplo, a classe Canino descreve as características e ações dos caninos em geral, enquanto o objeto Bandit representa um canino em particular.
Os atributos são estruturas de dados que armazenam informações sobre o objeto e os métodos são funções associadas ao objeto, que descrevem como o objeto se comporta.
No Python, novos objetos são criados a partir das classes através de atribuição. O objeto é uma instância da classe, que possui características próprias. Quando um novo objeto é criado, o construtor da classe é executado. Em Python, o construtor é um método especial, chamado __new__()
. Após a chamada ao construtor, o método __init__()
é chamado para inicializar a nova instância.
Um objeto continua existindo na memória enquanto existir pelo menos uma referência a ele. O interpretador Python possui um recurso chamado coletor de lixo (Garbage Collector) que limpa da memória objetos sem referências. Quando o objeto é apagado, o método especial __done__()
é evocado. Funções ligadas ao coletor de lixo podem ser encontradas no módulo gc.
Em Python:
Métodos especiais são identificados por nomes no padrão __metodo__()
(dois sublinhados no início e no final do nome) e definem como os objetos derivados da classe se comportarão em situações particulares, como em sobrecarga de operadores.
No Python, existem dois tipos de classes, chamadas old style e new style. As classes new style são derivadas da classe object e podem utilizar recursos novos das classes do Python, como properties e metaclasses. As properties são atributos calculados em tempo de execução através de métodos, enquanto as metaclasses são classes que geram classes, com isso permitem personalizar o comportamento das classes. As classes old style são uma herança das versões antigas do Python, mantidas para garantir compatibilidade com código legado.
Sintaxe:
In [ ]:
class Classe(supcl1, supcl2):
"""
Isto é uma classe
"""
clsvar = []
def __init__(self, args):
"""
Inicializador da classe
"""
<bloco de código>
def __done__(self):
"""
Destrutor da classe
"""
<bloco de código>
def metodo(self, params):
"""
Método de objeto
"""
<bloco de código>
@classmethod
def cls_metodo(cls, params):
"""
Método de classe
"""
<bloco de código>
@staticmethod
def est_metodo(params):
"""
Método estático
"""
<bloco de código>
obj = Classe()
obj.metodo()
Classe.cls_metodo()
Classe.est_metodo()
Métodos de objeto podem usar atributos e outros métodos do objeto. A variável self, que representa o objeto e também precisa ser passado de forma explícita. O nome self é uma convenção, assim como cls, podendo ser trocado por outro nome qualquer, porém é considerada como boa prática manter o nome.
Métodos de classe podem usar apenas atributos e outros métodos de classe. O argumento cls representa a classe em si, precisa ser passado explicitamente como primeiro parâmetro do método.
Métodos estáticos são aqueles que não tem ligação com atributos do objeto ou da classe. Funcionam como as funções comuns.
Exemplo de classe:
In [2]:
class Cell(object):
"""
Classe para células de planilha
"""
def __init__(self, formula='""', format='%s'):
"""
Inicializa a célula
"""
self.formula = formula
self.format = format
def __repr__(self):
"""
Retorna a representação em string da célula
"""
return self.format % eval(self.formula)
print Cell('123**2')
print Cell('23*2+2')
print Cell('abs(-1.45 / 0.3)', '%2.3f')
O método __repr__()
é usado internamente pelo comando print
para obter uma representação do objeto em forma de texto.
Em Python, não existem variáveis e métodos privados (que só podem ser acessados a partir do próprio objeto). Ao invés disso, é usada uma convenção, usar um nome que comece com sublinhado (_), deve ser considerado parte da implementação interna do objeto e sujeito a mudanças sem aviso prévio. Além disso, a linguagem oferece uma funcionalidade chamada Name Mangling, que acrescenta na frente de nomes que iniciam com dois sublinhados (__), um sublinhado e o nome da classe.
Exemplo:
In [3]:
class Calc:
def __init__(self, formula, **vars):
self.formula = formula
self.vars = vars
self.__recalc()
def __recalc(self):
self.__res = eval(self.formula, self.vars)
def __repr__(self):
self.__recalc()
return str(self.__res)
formula = '2*x + 3*y + z**2'
calc = Calc(formula, x=2, y=3, z=1)
print 'fórmula:', calc.formula
print 'x =', calc.vars['x'],'-> calc =', calc
calc.vars['x'] = 4
print 'x =', calc.vars['x'],'-> calc =', calc
print dir(calc)
O método __recalc()
aparece como _Calc__recalc()
e o atributo __res
como _Calc__res
para fora do objeto.
No Python, as classes que não são builtins podem ser alteradas em tempo de execução, devido a natureza dinâmica da linguagem. É possível acrescentar métodos e atributos novos, por exemplo. A mesma lógica se aplica aos objetos.
Exemplo de como acrescentar um novo método:
In [4]:
class User(object):
"""Uma classe bem simples.
"""
def __init__(self, name):
"""Inicializa a classe, atribuindo um nome
"""
self.name = name
# Um novo método para a classe
def set_password(self, password):
"""Troca a senha
"""
self.password = password
print 'Classe original:', dir(User)
# O novo método é inserido na classe
User.set_password = set_password
print 'Classe modificada:', dir(User)
user = User('guest')
user.set_password('guest')
print 'Objeto:', dir(user)
print 'Senha:', user.password
A classe modificada passou a ter um novo método: set_password()
.
In [1]:
Out[1]: