Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Duvida sobre o self

Em códigos que tem mais de uma classe, e uma que tem init usam bastente o self, mas qual é o criterio de utilização? em classes que não tem esse init precisa tambem usar o self nos metodos, variaveis e objetos?

2 respostas

Não consigo dar uma explicação definitiva, mas espero esclarecer alguns pointos.

Segundo o W3 Schools:

"O parâmetro self é uma referência para a instância atual de uma classe, e é usado para acessar atributos e metodos que pertencem a classe. Ele não tem que se chamar self, pode ser nomeado como você quiser, mas tem que ser o primeiro parâmetro de qualquer método da classe."

Na prática isso significa que abc e mysillyobject é o mesmo que self, isto é, referencia a instância atual, com seus próprios métodos e atributos. Todo primeiro parametro na definição dos metodos da classe fazem referencia ao objeto, à instância.

class Person:
  def __init__(mysillyobject, name, age):
    mysillyobject.name = name
    mysillyobject.age = age

  def myfunc(abc):
    print("Hello my name is " + abc.name)

p1 = Person("John", 36) # Aqui é criada uma instância da classe, ou um objeto.
p1.myfunc()

E respondendo à sua pergunta, mesmo sem o __init__ vc sempre precisa passar um self (ou qualquer nome) para os metodos na sua classe, mesmo que você não o utilize. Se vc não definir o python vai dar um erro, porque por de traz dos panos ele tenta passar a referencia da instância para o metodo, o que não funciona se não havia nenhum parametro self definido.

class ClasseFoo:
  def  minha_func(self):
      self.minha_outra_func()

  def minha_outra_func(self):
    print("Hello world") # não usa o self, mas minha_outra_func() precisa de pelo menos um parametro, no caso 'self' por mera convenção

p1 = ClasseFoo()
p1.minha_func()
solução!

Bom dia, Gabriel, tudo certo cntg?

Então vamos lá, uma ótima pergunta que me fez botar a mão na consciência e fritar um pouco kkkk espero que responda sua dúvida. Bem nós usamos o self quando queremos se referir a instância da classe, mas bem como isso funciona? Vamos criar uma classe para assistir isso funcionando.

class Teste:
    foo = "bar"
    def __init__(self):
        self.foo = "nao bar"

Criamos a classe Teste, nela nós declaramos um atributo chamado 'foo' que recebe a string 'bar' e tbm o método de inicialização/construção usando o self com um atributo com mesmo nome 'foo', mas quando nós chamamos a classe, quem é que aparece?

No python nós podemos utilizar uma classe sem o método init como comentado, com seus atributos ficando no escopo (?) da classe, as mudanças ficam no objeto da classe, no caso o 'Teste', bora ver isso:

Teste.foo
>>> 'bar'

Quando chamamos a classe com seu atributo recebemos o valor padrão do objeto, não chegando a iniciar e então receber o valor do self.foo = 'nao bar', a gente não "instanciou" a classe, não criamos um novo objeto a partir dela, nós utilizamos o próprio objeto da classe, para isso não foi necessário o self, porém agora utilizando o init com uma instância dessa classe.

t = Teste()
t.foo
>>> 'nao bar'

Criamos um novo objeto, instanciamos a classe e a partir dela conseguimos interagir com ela, olha que dahora, possuem o mesmo nome como atributo, o 'foo', porém ele recebe o valor do método de inicialização, que temos a palavra-chave self, que está representando agora o "t", então dentro da nossa classe quando vemos o "self", ele significa o 't', que é o nome da instância da classe que fizemos, olha nós podemos chamar o atributo novamente da classe para ver se ele vai retornar o valor dentro do init ou do escopo geral da classe.

Teste.foo
>>> 'bar'

Ele retorna o 'bar' o valor padrão que passamos no começo, como um acabou não influenciando o outro, mas tomar cuidado que podem acabar confundindo as coisas, não acaba sendo uma boa prática, até não saberia te falar uma prática que isso seja usado, pela pouca experiencia que tive ainda não precisei usar um atributo de fora da classe da inicialização.

Temos uma pergunta parecida com outro conteúdo no stack, da uma olhada, pode ajudar tbm: https://pt.stackoverflow.com/questions/109013/quando-devo-usar-init-em-fun%C3%A7%C3%B5es-dentro-de-classes