Para definir atributos de uma classe devo colocá-los sempre no método "init" ou tem outro jeito ou lugar?
Para definir atributos de uma classe devo colocá-los sempre no método "init" ou tem outro jeito ou lugar?
Carlos, o método __init__
do Python é por definição o inicializador de uma instância da sua classe.
Por exemplo:
class Cachorros:
def __init__(self, patas, cor):
self.patas = patas
self.cor = cor
fido = Cachorros(4, "preto")
bidu = Cachorros(3, "marrom")
Fido e bidu são instâncias (objetos) da sua classe Cachorros, e ao definí-los caracterizando suas patas e suas cores, o Python, por meio do init "inicializou" instâncias da classe. O self
se refere à instância, ou seja, o self
de fido
é o próprio fido
.
Ou seja, você tem a classe Cachorros
e fido
e bidu
são instâncias da sua classe que foram inicializadas pelo __init__
quando você criou as instâncias.
Se você quiser saber os atributos de cada objeto, pode fazer:
fido.cor
retorna 'preto'
Por definição você deve usar o __init__
para criar objetos (instâncias) das suas classes. E por isso geralmente a primeira função que você cria ao criar uma classe é o __init__
.
Não sei se fui claro, é meio confuso mesmo no início. Se continuar com dúvida posta aí.
Entendi seu exemplo mas a minha pergunta é se um atributo pode ser criado fora do init Entendo que o init inicializa um atributo, mas eu quero saber se os atributos podem ser declarados fora do init Agradeço pela primeira resposta mas, se possível, espero por uma outra. Talvez o código abaixo dê sentido na minha pergunta.
class Cachorros:
# Atributos:
patas = 0
cor = ""
Ah, perdão se não entendi direito a pergunta e expliquei outra coisa.
Se o atributo pode ser criado fora do __init__
:
Mesmo exemplo acima, mas de outra forma:
class Cachorros:
def __init__(self, patas):
self.patas = patas
def define_cor(self, cor):
self.cor = cor
No console:
bidu = Cachorros(4)
bidu.patas
O retorno do pedido é 4
Agora, para definir a cor, você tem que chamar a nova função e passar a cor como parâmetro:
bidu.define_cor("preto")
bidu.cor
O retorno é "preto"
.
O mesmo exemplo sem __init__
:
class Cachorros:
def define_cachorro(self, patas, cor):
self.patas = patas
self.cor = cor
No console você deve criar a instância primeiro para só depois passar os atributos da instância. Você acaba escrevendo mais para no final ter o mesmo resultado:
bidu = Cachorros()
bidu.define_cachorro(4, "preto")
bidu.cor
O retorno dos atributo "cor" trará "preto"
normalmente no console, mas assim você digitou uma linha a mais de código para obter o mesmo resultado.
Usar o __init__
é uma boa prática de programação em Python. Não usá-lo deixa seu código mais "hardcoded" e você precisa digitar mais código pra obter o mesmo resultado.
Então, via de regra, ao criar um objeto de sua classe você usa o __init__
e já passa os parâmetros iniciais para o objeto no momento de criação da instância.
Entretanto, no seu exemplo, você já criou cor e pata por default, o que pode ser feito sem problema. Você pode criar a classe assim:
class Cachorros:
cor = "preto"
patas = 4
E ao instanciar qualquer objeto sem passar parâmetro algum, ele já trará a cor preta e 4 patas como atributos dele.
bidu.patas
retorna 4
por default
Você pode alterar o atributo dessa forma:
bidu.patas = 5
E o retorno trará 5 normalmente, mas isso, o ato de "forçar" uma mudança em atributo no console sem usar uma função setter para tal, não é considerado uma boa prática em Python. Para fazer isso você terá que definir um setter
na classe, que será assunto abordado no decorrer do curso de Programação Orientada a Objetos em Python.
Em resumo:
Se seus atributos são variáveis de acordo com o objeto instanciado (por exemplo, nem todo cachorro é preto), o ideal é usar o __init__
e passar os atributos ao instanciar o objeto da classe.
Entretanto, você pode definir que todos os objetos da sua classe vão ter sempre o mesmo atributo por padrão (como definir que todo cachorro tem 4 patas) e passar esse atributo fora de qualquer função mas dentro da classe, o que pode ser feito sem problema. Mas alterar esse atributo "à força" sem um setter
é considerado má prática.
Essa resposta era mais o menos o que você queria saber? Espero que dessa vez eu tenha entendido a pergunta haha