Um programador PHP entendendo Pyhton
Pro resto do mundo, Python é uma linguagem fácil de assimilar. Pro resto do mundo. Pra mim é algo muito novo, bem distante do C++, e tenho tido certa dificuldade. Por isso decidi começar a escrever mais sobre o Python e aprender a usar isso aí.
<?php
class Interruptor {
$estado;
function __construct($estadoInicial = 'desligado') {
$this->estado = $estadoInicial;
}
function lerEstado() {
return $this->estado;
}
function alterarEstado() {
if($this->estado == 'desligado') {
$this->estado = 'ligado';
} else {
$this->estado = 'desligado';
}
}
Agora eu posso criar um interruptor:
<?php
include "Interruptor.class.php"
$rup = new Interruptor();
... ler o seu estado...
echo $rup->lerEstado();
... e alterá-lo...
$rup->alterarEstado();
Pois bem. Agora preciso criar um interruptor desses em Python. Vai ficar assim:
class Interruptor:
def __init__(self, estado_inicial = 'desligado'):
self.estado = estado_inicial
def lerEstado(self):
return self.estado
def alterarEstado(self):
if self.estado == 'desligado':
self.estado = 'ligado'
else:
self.estado = 'desligado'
Para usar a classe (perceba que ">>>" indica que dei o comando diretamente no shell do Python):
>>> from Interruptor import Interruptor
>>> rup = Interruptor()
>>> print(rup.lerEstado())
Desligado
>>> rup.alterarEstado()
>>> print(rup.lerEstado())
Ligado
- O método construtor de uma classe Python é o __init__.
- Mesmo que um método não receba parâmetro algum, é preciso que o "self" esteja lá.
- Os blocos são separados pela indentação do código. Em PHP, independente do código estar bem indentado ou não, os blocos ficam entre chaves. Note a diferença:
//PHP
if(true) {
echo 'ok';
} else {
echo 'not ok';
}
//Python
if True:
print("ok")
else:
print("not ok")
É uma maneira efetiva de forçar o aluno a escrever um código bem indentado, sob pena do programa não funcionar.
- Usar parênteses no teste lógico do "if" é opcional;
- Assim como a indentação determina um bloco de código, a mudança de linha indica o fim de uma sentença e o início da outra. Em PHP usamos o ponto-e-vírgula pra isso.
- Os métodos são identificados pela palavra "def", de definição. Em PHP usamos "function". Usar "def" economiza digitação. Somando todas as outras coisas que desaparece (';', '(', ')', '{', '}', etc.), acaba que fica menos custoso digitar um código Python, mas discordo com a maioria quando dizem que o código é mais legível.
Entre outros. Na verdade existe uma infinidade de métodos especiais, e, honestamente, de todos os que conheço, nenhum é inútil. Python possui um número muito maior de "métodos mágicos" e o objetivo deles é fazer uma classe se comportar de modo extremamente compatível com o sistema. Por exemplo, veja a classe Interruptor com a adição de uma documentação básica.
class Interruptor(object):
"""Ativa/Desativa um interruptor qualquer"""
def __init__(self, estado_inicial = 'desligado'):
self.estado = estado_inicial def lerEstado(self):
return self.estado def alterarEstado(self):
if self.estado == 'desligado':
self.estado = 'ligado'
else:
self.estado = 'desligado'
Agora se, após instanciado, eu chamar...
>>> rup.__doc__
'Ativa/Desativa um interruptor qualquer'
Obterei o texto da documentação da classe. Isso é bom. Posso documentar toda a classe usando esse recurso, o que livra qualquer um do trabalho de descobrir o que fiz quando a criei, quais métodos e propriedades existem, etc.
>>> import Interruptor
>>> rup = Interruptor()
>>> rup.lerEstado()
Mas assim funciona:
>>> from Interruptor import Interruptor
>>> rup = Interruptor()
>>> rup.lerEstado()
'desligado'
E assim também:
>>> import Interruptor
>>> rup = Interruptor.Interruptor()
>>> rup.lerEstado()
'desligado'
Pois, no primeiro e no terceiro caso, import Interruptor importa apenas o arquivo, daí tenho que dizer qual classe desse arquivo quero instanciar. Posso fazer isso com Interruptor.Interruptor ou, quando importar o arquivo, pegar só a classe que quero: from Interruptor import Interruptor.
Dessa maneira, passei a olhar o Python de um jeito mais interessado. Ele entrega muita coisa interessante, e, por isso talvez, ignorá-lo não seja mais uma opção.
Uma classe pra chamar de minha
Uma classe é basicamente um um conjunto de métodos e propriedades. A classe costuma representar algo no mundo real, como, por exemplo, um interruptor. Se eu quiser criar, em PHP, uma classe para tratar um interruptor, vai ficar semelhante a isso:<?php
class Interruptor {
$estado;
function __construct($estadoInicial = 'desligado') {
$this->estado = $estadoInicial;
}
function lerEstado() {
return $this->estado;
}
function alterarEstado() {
if($this->estado == 'desligado') {
$this->estado = 'ligado';
} else {
$this->estado = 'desligado';
}
}
Agora eu posso criar um interruptor:
<?php
include "Interruptor.class.php"
$rup = new Interruptor();
... ler o seu estado...
echo $rup->lerEstado();
... e alterá-lo...
$rup->alterarEstado();
Pois bem. Agora preciso criar um interruptor desses em Python. Vai ficar assim:
class Interruptor:
def __init__(self, estado_inicial = 'desligado'):
self.estado = estado_inicial
def lerEstado(self):
return self.estado
def alterarEstado(self):
if self.estado == 'desligado':
self.estado = 'ligado'
else:
self.estado = 'desligado'
Para usar a classe (perceba que ">>>" indica que dei o comando diretamente no shell do Python):
>>> from Interruptor import Interruptor
>>> rup = Interruptor()
>>> print(rup.lerEstado())
Desligado
>>> rup.alterarEstado()
>>> print(rup.lerEstado())
Ligado
Diferenças
- A primeira diferença, de cara, é o "self". No PHP, "self" já é subentendido, não precisa ser declarado. Ele será acessado sempre que for necessário usando "$this", para propriedades, ou "self::", para métodos.- O método construtor de uma classe Python é o __init__.
- Mesmo que um método não receba parâmetro algum, é preciso que o "self" esteja lá.
- Os blocos são separados pela indentação do código. Em PHP, independente do código estar bem indentado ou não, os blocos ficam entre chaves. Note a diferença:
//PHP
if(true) {
echo 'ok';
} else {
echo 'not ok';
}
//Python
if True:
print("ok")
else:
print("not ok")
É uma maneira efetiva de forçar o aluno a escrever um código bem indentado, sob pena do programa não funcionar.
- Usar parênteses no teste lógico do "if" é opcional;
- Assim como a indentação determina um bloco de código, a mudança de linha indica o fim de uma sentença e o início da outra. Em PHP usamos o ponto-e-vírgula pra isso.
- Os métodos são identificados pela palavra "def", de definição. Em PHP usamos "function". Usar "def" economiza digitação. Somando todas as outras coisas que desaparece (';', '(', ')', '{', '}', etc.), acaba que fica menos custoso digitar um código Python, mas discordo com a maioria quando dizem que o código é mais legível.
Além do __init__
Em PHP temos os chamados "métodos mágicos". Alguns deles são o próprio __construct(), __get, __set, __toString(). O que se assemelha a isso em Python são os chamados "métodos especiais". O __init__ é equivalente ao __construct; o __str__ é equivalente ao __toString(), e por aí vai.Preciso... | PHP | Python |
---|---|---|
Inicializar o objeto | __construct([$param(s)]) | __init__(self[,param(s)]) |
Transformar o objeto em texto | __toString() | __str__(self[,param(s)]) |
Tratar a chamada a um atributo | __get($atributo) | __getattr__(self, name) |
Alterar o valor de um atributo | __set($atributo, valor) | __setattr__(self, name, value) |
Entre outros. Na verdade existe uma infinidade de métodos especiais, e, honestamente, de todos os que conheço, nenhum é inútil. Python possui um número muito maior de "métodos mágicos" e o objetivo deles é fazer uma classe se comportar de modo extremamente compatível com o sistema. Por exemplo, veja a classe Interruptor com a adição de uma documentação básica.
class Interruptor(object):
"""Ativa/Desativa um interruptor qualquer"""
def __init__(self, estado_inicial = 'desligado'):
self.estado = estado_inicial def lerEstado(self):
return self.estado def alterarEstado(self):
if self.estado == 'desligado':
self.estado = 'ligado'
else:
self.estado = 'desligado'
Agora se, após instanciado, eu chamar...
>>> rup.__doc__
'Ativa/Desativa um interruptor qualquer'
Obterei o texto da documentação da classe. Isso é bom. Posso documentar toda a classe usando esse recurso, o que livra qualquer um do trabalho de descobrir o que fiz quando a criei, quais métodos e propriedades existem, etc.
Conclusão
Estava com o pé atrás quando comecei a escrever esse artigo. Acontece que minhas classes nunca funcionavam e fiquei extremamente frustrado com isso. Também procurei aprender Python através de um livro que não teve a melhor tradução do mundo (Programação em Python 3 - Uma Introdução Completa à Linguagem Python. Não compre. Sério, não compre.). Depois eu aprendi que o problema estava na maneira como invoquei a classe. Assim não funciona:>>> import Interruptor
>>> rup = Interruptor()
>>> rup.lerEstado()
Mas assim funciona:
>>> from Interruptor import Interruptor
>>> rup = Interruptor()
>>> rup.lerEstado()
'desligado'
E assim também:
>>> import Interruptor
>>> rup = Interruptor.Interruptor()
>>> rup.lerEstado()
'desligado'
Pois, no primeiro e no terceiro caso, import Interruptor importa apenas o arquivo, daí tenho que dizer qual classe desse arquivo quero instanciar. Posso fazer isso com Interruptor.Interruptor ou, quando importar o arquivo, pegar só a classe que quero: from Interruptor import Interruptor.
Dessa maneira, passei a olhar o Python de um jeito mais interessado. Ele entrega muita coisa interessante, e, por isso talvez, ignorá-lo não seja mais uma opção.
Comentários
Postar um comentário