Este é o último nivel que abordamos na aprendizaxe de Python. Non o facemos de xeito práctico, senón para fomentar a lectura e reutilización (isto é, copiar no bo sentido) de código xa feito.
Se lemos programas de complexidade media en Python ou os seus comentarios, o normal é que pareza todo moi raro, con un montón de conceptos descoñecidos, ou, aínda peor, confundidos con outros: clase, atributo. instancia, obxecto...
A idea desta páxina é que volvas cando teñas confunsión cun termo, e repases os conceptos. O obxectivo é que non soe a chino o que aparece neste código:
Este código é a parte inicial do famoso xogo do Pong escrito para a biblioteca de Pygame. En concreto o código para crear a bola que se move polo escenario e interactúa coas raquetas. Nesta páxina imos intentar aclarar que significa: class, self, __init__ porque son cousas que vas atopar seguido en calquera programa de complexidade media.
Python é un tipo de linguaxe de programación chamado multiparadigma, o cal significa que está construído dende a base utilizando distintas modalidades de linguaxes de programación. Dos tipos de paradigmas que están na base de Python os máis importantes son:
- O paradigma da programación estruturada, empregado nos algoritmos sinxelos, os que teñen unha ou varias funcións (ou ordes secuenciadas), que collen uns datos e devolven outros datos. Por exemplo, calcular o factorial dun número. Estes algoritmos son para aprender programación é tamén para aprender a dividir un problema (programa) complexo nunha sucesión de problemas (subprogramas) sinxelos. Estes algoritmos son os que temos utilizado na parte de Scratch a Python.
- O paradigma da programación orientada a obxectos, empregado nos algoritmos de complexidade media. Este paradigma ou metodoloxía de programación, chamado POO (ou OOP en inglés) é a base de moitos linguaxes de programación importantes, polo que unha das vantaxes de aprender isto en Python é que facilita enormemente aprender unha segunda linguaxe de programación se tamén é orientada a obxectos. En concreto poderías aprender facilmente Javascript se saber ler un código de Python como o anterior. Se queres ler con calma de que vai isto dos obxectos, podes ler nesta páxina.
As palabras/conceptos que necesitas ter claro para poder ler Python en modalidade POO son:
obxecto - atributo - clase - método - instancia
A isto temoslle que engadir: función, parámetro, variable, tipos de datos, estrutura de datos....
Vexamos como pode afectarnos isto para ler programas de Python. A diferencia vai estar na dificultade de partida do algoritmo a escribir ou ler (e polo tanto do problema a resolver ou o comportamento a implementar)
Tipo de algoritmos según complexidade | Palabras e conceptos que atopamos ao ler | Diagrama básico |
Sinxela ou media nalgúns casos | Función, método, parámetro, argumento, biblioteca ou módulo, datos simples, datos estruturados lineais. |
|
Media |
Todos os anteriores e ademais: clase, instancia, obxecto, atributo... |
|
Programando obxectos
Para nós os obxectos son aquilo concreto que imos programar (un algoritmo que toma uns valores de entrada e devolve uns valores, ou un comportamento, de saída, pero tamén a interación cos outros obxectos). En Scratch serían os sprites ou monecos. Aquí é un pouco máis lioso, porque os obxectos poden estar compostos por outros obxectos. Pero para entendelo mellor pensar así: un obxecto e algo que programamos (entrada-saída-comportamento).
Os obxectos poden executar funcións, escritas por nós ou chamadas dende o programa, chamadas métodos, que dependen de valores de entrada, chamados parámetros, e poden ter diversas propiedades ou condicións, chamados atributos. Por exemplo un obxecto 'Serpe Pitón' pode ter unha función para moverse coas frechas do teclado e un atributo, propiedade, de 'non é velenosa' e outra de 'peso'.
Aínda hai clases
Na programación orientada a obxectos hai unha metodoloxía moi útil (pero pode que confusa ao incio). Se crea unha clase, que ven sendo como un molde ou planilla base formada por varias funcións (métodos) e parámetros (argumentos), un molde con certas propiedades, e os obxectos e as interacións entre obxectos se crean a partir das clases definidas previamente. Imos velo coa serpe de AlgoRitmia.
|
|
|
Isto representámolo dicindo que os obxectos, que forman a base do noso programa, son instancias de clase. Collemos o molde da clase e creamos un ou varios obxectos concretos. Por exemplo coa clase Serpe(), creamos unha pitón ou unha víbora. As dúas son serpes, o cal quere decir que teñen propiedades e funcións en común, como por exemplo o seu subgrupo ('Reptil') pero logo terán propiedades, atributos, distintos, como o nome ou o feito de ser velenosas ou non.
|
|
Se queres afondar máis nesta páxina comentan con calma o concepto de clase, e nestoutra comentan paso a paso o famoso videoxogo Pong en función dos conceptos de programación orientada a obxectos.
Crear unha clase: o uso de self
Imos crear serpes concretas, obxectos, que teñan propiedades concretas (nome, ser velenosa) pero partindo dun molde previo chamado clase. Crear unha clase é como crear unha función (que logo estará composta de outras funcións), pero usando a palabra class:
class Serpe():
As clases terán unhas variables que son as propiedades, que logo terán valores concretos nos obxectos.
As clases comezan todas cunha función ou método inicial, chamada __init__ que terá como parémetros as propiedades que vaian ter os futuros obxectos (o nome da serpe é unha variable que toma valores concretos en cada serpe), e ademais o primeiro parámetro sempre será self. Isto por que?. Self é o argumento (parámetro) que lle di ao método que estamos a aplicalo sobre o noso obxecto concreto. Confuso?. O mellor é practicar.
Apunte lingüístico: a norma para poñer nomes ás clases é CamelCase.
Imos crear diferentes serpes que teñan as seguintes propiedades (atributos): o nome, subgrupo animal e se é velenosa. En función destes valores teremos saídas diferentes.
Creamos o método inicial, que contén os 3 parámetros ou argumentos que imos utilizar para caracterizar á nosa serpe, o noso obxecto, e ademais self en primeiro lugar :
class Serpe():
def __init__(self, nome, subgrupo, veleno):
self.nome = nome
self.subgrupo = subgrupo
self.veleno = veleno
A función __init__ é coñecida en moitas páxinas como constructor.
Temos creadas unhas variables que poden almacenar os valores concretos (cando os teñamos) dunha serpe concreta (obxecto). Son chamadas self.nome, self.subgrupo e self.veleno. Agora creamos unha función, quen_son(), para utilizar o valor concreto do nome e do subgrupo:
class Serpe():
def __init__(self, nome, categoria, veleno):
self.nome = nome
self.subgrupo = subgrupo
self.veleno = veleno
def quen_son(self):
print ('Ola, son a ', self.nome, ' e polo tanto son un ', self.categoria)
Importante: o argumento desta función é só self por que logo utilizamos self.nome para almacenar o valor concreto do nome dunha serpe concreta.
Crear un obxecto dentro dunha clase
Agora imos crear o noso obxecto facendo unha instancia, que ten uns atributos ou propiedades concretas, partindo da clase Serpe():
serpe1 = Serpe("Víbora", "Reptil", True)
Importante: Fíxate que na clase temos 4 parámetros ou valores e no obxecto 3. O outro é o inicial, self, e non temos que indicalo.
Pois agora podemos usar serpe1 como conxunto de datos e métodos, un obxecto, ao que podemos aplicar algún método concreto usando a sintaxe:
nome_do_obxecto.método()
Por exemplo:
serpe1.quen_son() #neste caso esto viría sendo o noso programa
Resumimos na seguinte táboa o que temos feito:
Programa | Serve para |
---|---|
class Serpe(): | Dámoslle nome a unha nova clase |
def __init__(self, nome, categoria, veleno): self.nome = nome self.subgrupo = subgrupo self.veleno = veleno |
Esta clase terá 4 parámetros, pero so teremos que especificar 3 deles, porque o cuarto é o parámetro self. |
def quen_son(self): print ('Ola, son a ', self.nome, ' e polo tanto son un ', self.categoria) |
Definimos un método: unha función que funcionará para todos os obxectos desta clase. Este método indica un comportamento da clase: é un saúdo. |
serpe1 = Serpe("Víbora", "Reptil", True) |
Defino un obxecto que pertence á clase Serpe, é dicir: unha instancia . Por tanto coa función __init__ gardarase o seguinte:
|
serpe1.quen_son() | Chamo ao método quen_son da clase á que pertence serpe1 |
Podes fixarte que o de usar subgrupo como variable é un pouco parvo, pois todas as serpes son Reptís. Si, pero é para indicar un exemplo de parámetro constante. Nos exercicios podes modificar a función para que non use este parámetro.
Engadir outra función na clase
Engadimos outra función que use o parámetro de se unha serpe é velenosa ou non:
def velenosa(self):
if self.veleno:
print('Son velenosa')
else:
print('Tranqui, non mordo...moito')
Como ves, o único argumento da función é self. Pero poderíamos utilizar outros parámetros.
Crear outro obxecto
serpe2 = Serpe("Pitón", 'Reptil', False)
Crear un programa
Agora poderemos crear un programa chamando as funcións que desexemos das nosas serpes. Neste caso tan sinxelo non hai moito que poidamos facer:
serpe1.quen_son()
serpe1.velenosa()
serpe2.quen_son()
serpe2.velenosa()
Exercicios:
- Modifica o programa para prescindir do argumento subgrupo (pero que siga dicindo cada serpe que é un reptil)
- Modifica o programa para que use un bucle de consulta. Tes unha proposta na parte de abaixo do código
- Modifica a clase para que as serpes que non son velenosas dean unha frase tipo 'Coidado, non pisar!'
- Crea a túa clase e os teus obxectos en base a estes.
Non remata aquí todo o que podes aprender de Python. Tes que saber que hai outros conceptos ou características importantes de POO que sairán en moitas páxinas de Python:
polimorfismo-herencia-abstración-encapsulamiento e outras
Para copiar Python
Copiar e modificar un programa xa creado é un dos métodos fundamentais para aprender a programar. Pero temos que saber como ler ese código.
O problema principal que vas ter é non recoñecer os métodos dun programa, en especial os que veñan dun módulo ou biblioteca. Contra isto non hai solución, paciencia, ler con calma e buscar información en internet.
Pero podes aprender sobre eses métodos vendo a estrutura do programa e identificando as partes. Se os nomes están ben empregados pode ser máis sinxelo do que parece.
Como norma xeral nos programas de dificultade media teremos esta estrutura de programa:
Diagrama de bloques dun programa medio | Exemplo de estrutura en Python |
---|---|
|
No xogo aliens que ven de exemplo en Pygame (e do que xa falamos na páxina de Pygame) teremos esta estrutura. Podes comprobalo baixando o programa.
if __name__ == '__main__':
Este comando, que aparece no bucle principal é, basicamente, a maneira de executar os programas cando estamos en modo POO. Se queres ler unha boa explicación podes ir a esta páxina.
Unha boa páxina web para ler e copiar Python é Programar xogos de arcade en Python e Pygame .