Ej. 42 : Practicando con objetos y clases…

Un concepto importante que hay que entender es la diferencia entre una clase y un objeto. El problema es que no existe una diferencia real entre ambos. Pero en realidad son lo mismo en diferentes puntos del tiempo.

Por ejemplo, ¿cuál es la diferencia entre un pez y un salmón?

Un salmón es un tipo particular de pez.

Voy a llamar al salmón Agustín.

¿Cuál es la diferencia entre Agustín y un salmón?

Ninguna. Agustín es una INSTANCIA de un salmón. Agustín ha sido «creado» a partir de algún otro salmón, y ahora es una cosa real que tiene atributos como salmón.

Avanzo.

El pez es una clase, el salmón es una clase y Agustín es un objeto.

Mmmmm

Un pez es una clase, lo que significa que es no es algo real, sino más bien una palabra ABSTRACTA que ATRIBUIMOS a INSTANCIAS de cosas con atributos similares. ¿Tiene aletas? ¿Branquias? ¿Vive en el agua? Bien. Probablemente es un pez.

Entonces, una persona con un doctorado viene y nos dice: «No, mi joven amiga, éste pez es en realidad un Salmo salar, vulgarmente conocido como salmón», Éste profesor sólo ha hecho una aclaración más del pez y ha creado una nueva clase llamada «salmón» que tiene atributos específicos. ¿Tiene una nariz larga, carne rojiza, es grande, vive en el mar o en agua dulce y es sabroso? Bien. Probablemente sea un salmón.

Por último, viene un cocinero y le dice al doctor: «Voy a llamar a éste salmón Agustín, y lo cocinaré a la papillote. Es una de mis especialidades. Quedará exquisito». Ahora tengo esa instancia de un salmón, que también es una instancia de un pez, llamado Agustín, que se convirtió en algo real y fué fileteado. XD Se ha convertido en un objeto.

Así que AGUSTÍN ES UN OBJETO, UN TIPO DE SALMÓN DE LA CLASE PEZ.

A ver. Entonces, ¿Un objeto es una clase pero no todas las clases son objetos? Mmmmm.

En éste caso:

  • Pez = clase
  • Salmón = clase
  • Agústín = objeto, instanciado(creado) por la clase salmón

Perfect!!

CÓMO ES ÉSTO EN CÓDIGO

¿Clase u objeto?

Un truqui:

ES-UN para objetos y/o clases que se relacionan entre si por una relación de clase (relación pez-salmón).

TIENE-UN para objetos y clases que sólo están relacionados porque hacen referencia entre si (relación salmón-branquia).

Vamos a ver si lo he entendido.

Ej. 42 - Editor 1Ej. 42 - Editor 2 Ej. 42 - Editor 3Todos mis comentarios pueden no estar bien. Son suceptibles de cambio.

ACERCA DE LAS CLASS NOMBRE (OBJECT)

Como ya he visto las diferencias entre clase y objeto, sólo añadir que Python siempre requiere (object) cuando crea una clase.

En realidad, una clase hereda de otra clase llamada object para crear su clase, pero no es objeto. Algo confuso.

Ésto viene de la interpretación original que Python le dió a la clase, y de la fusión entre las clases viejas y las nuevas.

No digo más que me lío sola. 😛

 PREGUNTAS

P: ¿Qué es el punto de self.pet = None?

R: Asegura que el atributo self.pet de esa clase se le asigna el valor None.

P: ¿Qué hace super(Employee, self).__init__(name)?

R: Así es como se ejecuta el método __init__de una clase padre con seguridad. Busca «python super» y los diversos consejos sobre su uso.

P: ¿Es posible usar una clase como un objeto?

R: Interesante pregunta. ¿Tú qué crees?

P: Mmmmm

Ej. 41 : Aprendiendo a hablar orientado a objetos…

En éste ejercicio voy a aprender cómo hablar «orientado a objetos». Voy a practicar con un pequeño conjunto de palabras que necesito conocer junto con sus definiciones. Luego practicaré con una serie de frases con huecos y tendré que entender su significado. Por último, escribiré un gran conjunto de ejercicios que tengo que completar para crear así frases sólidas en mi vocabulario.

PRACTICANDO CON LAS PALABRAS

  • class – Le dice a Python que cree un nuevo tipo de cosa.
  • objeto – Tiene dos significados: el tipo de cosa más simple y cualquier instancia de alguna cosa.
  • instancia – Lo que obtengo cuando le digo a Python que cree una clase.
  • def – Para definir una función dentro de una clase.
  • self – Dentro de las funciones de una clase, self es una variable de la instancia/objeto al que se acaba de acceder.
  • herencia – el concepto de que una clase puede heredar aspectos de otra clase, al igual que usted de sus padres.
  • composición – El concepto de que una clase puede estar compuesta de otras clases, al igual que un coche tiene ruedas.
  • atributo – Una propiedad que tienen las clases, y suelen ser variables.
  • es-un – Una frase empleada para decir que algo hereda de otra cosa, como un «salmón» es-un «pez».
  • tiene-un  – Una frase para decir que algo está compuesto de otras cosas o tiene un rasgo, como «un salmón tiene-una boca».

PRACTICANDO CON LAS FRASES

A continuación, tengo una lista de fragmentos de código Python, seguido de su significado.

  • class X(Y) «Crea una clase llamada X que tiene-un Y».
  • class X(object): def __init__(self, J) «La clase X tiene-un __init__ que recibe por parámetro self y J.»
  • class X(object): def M(self, J)  «La clase X tiene-una función llamada M que recibe por parámetro self y J».
  • foo = X()  «Asigna a foo una instancia de la clase X»
  • foo.M(J)  «Desde foo se obtiene la función M y la llama pasándole por parámetro self,J.»
  • foo.K = Q «Desde foo se obtiene el atributo K y le asigna Q.»

En cada una de esas frases, puedo tratar X, Y, M, J, K, Q y foo como espacios en blanco. Por ejemplo, podría escribir las mismas frases de la siguiente manera.

  • «Crea una clase llamada ??? que tiene-un Y.»
  • «La clase ??? tiene-un __init__ que recibe por parámetro self y ??? .»
  • «La clase ??? tiene-una función llamada ??? que recibe por parámetro self y ???.»
  • «Asigna a foo una instancia de la clase ???»
  • «Desde foo se obtiene la función ??? y la llama pasándole por parámetro self, ???.»
  • «Desde foo se obtiene el atributo ??? y le asigna ??? «

PRACTICANDO CON AMBAS

Ahora voy a combinar los ejercicios de palabras con los ejercicios de las frases. Tengo que hacer lo siguiente:

  1. Tomar una de las notas de las frases y practicar con ella.
  2. Darle la vuelta, leer la frase y cada una de las palabras de la frase que esté en los ejercicios de las palabras, recuperar las notas de las palabras.
  3. Practicar con esas palabras de esas frases.
  4. Seguir haciéndolo

UNA PRUEBA DE LECTURA

Voy a hacer un pequeño programa Python con el que practicar las palabras que ya conozco. Lo único que hace es usar una librería llamada urllibr para descargar una lista de palabras que tengo. Éste es el código. Debería entrar en opp_test.py para trabajar con él.

1    import random
2    from urllib import urlopen
3    import sys
4    
5    WORD_URL = "http://learncodethehardway.org/words.txt"
6    WORDS = []
7    PHRASES = {
8        "class %%%(%%%):":
9        "Make a class named %%% that is-a %%%.",
10       "class %%%(object):\n\tdef __init__(self, ***)" :
11       "class %%% has-a function named *** that takes self and *** parameters.",
12       "class *** (object):\n\tdef ***(self, @@@)":
13       "class %%% has-a fuction named *** that takes self and @@@ parameters",
14       "*** = %%%()":
15       "Set *** to an instance of class %%%.",
16       "***.***(@@@)":
17       "From *** get the *** function, and call it with parameters self, @@@.",
18       "***.*** = '***'":
19       "From *** get the *** attribute and set it to '***'."
21   }
22
23   # Si quiero practicar primero con frases
24   PHRASE_FIRST = False 
25   if len(sys.argv) == 2 and sys.argv[1] == "english":
26   PHRASE_FIRST = True
27   
28   # Carga las palabras de la pagina web
29   for word in urlopen(WORD_URL).readlines():
30   WORDS.append(word.strip())
31   
32 
33   def convert (snippet, phrase):
34       class_names = [w.capitalize() for w in 
35           random.sample(WORDS, snippet.count("***"))]
36       other_names = random.sample(WORDS, snippet.count("***"))
37       results = []
38       param_names = []
39   for i in range(0, snippet.count("@@@")):
40   param_count = random.randint(1,3)
41   param_names.append(', '.join(random.sample(WORDS, param_count)))
42
43
44   for sentence in snippet, phrase:
45       result = sentence[:]
46   # Nombres falsos de clase
47   for word in class_names:
48       result = result.replace("%%%", word, 1)
49   
50   # Otros nombres falsos
51   for word in other_names:
52       result = result.replace("***", word, 1)
53
54 
55   # Lista de parametros falsos
56   for word in param_names:
57       result = result.replace("@@@", word, 1)
58   
59       results.append(result)
60 
61   return results
62 
63
64   # Se ejecuta hasta pulsar CTRL- D
65   try:
66       while True:
67           snippets = PHRASES.keys()
68           random.shuffle(snippets)
69
70       for snippet in snippets:
71           phrase = PHRASES[snippet]
72           question, answer = convert (snippet, phrase)
73           if PHRASE_FIRST:
74                   question, answer = answer, question
75
76           print question
77
78           raw_input("> ")
79           print "ANSWER: %s\n\n" % answer
80   except EOFError:
81       print "\nBye"

Ejecuto el código e intento traducir las «frases orientadas a objetos» a nuestro idioma.

Y tras depurar varios errores me sale lo siguiente:Ej. 41 - Terminal 1

Nota: El diccionario PHRASES tiene ambas formas y hay que usar la correcta.

PRACTICANDO DE NUESTRO IDIOMA A CÓDIGO

A continuación, debo ejecutar el código con la «english» para practicar la opción inversa.

Éstas frases están utilizando palabras sin sentido. Parte del aprendizaje para leer código consiste en dejar de poner mucho significado en los nombres usados para variables y clases.

LEYENDO MÁS CÓDIGO

Voy a leer más código, y ésta vez, para leer las frases que acabo de aprender. Tengo que buscar todos los ficheros con clases y hacer lo siguiente:

  1. Para cada clase, anotar su nombre y escribir qué otras clases heredan de ella.
  2. Debajo de ésto, anotar un listado de todas las funciones que tiene y todos los parámetros que reciben.
  3. Hacer una lista de todos los atributos uados con self.
  4. Para cada atributo, escribir a qué clase pertenece.

El objetivo es revisar código real y empezar a aprender a «reconocer los patrones» de las frases que he aprendido y cómo se usan. Si practico lo suficiente, se supone que debería de empezar a ver esos patrones en el código, entre tanto, parecerán esos espacios en blanco que desconozco.

PREGUNTAS

P: ¿Qué hace result = sentence [:]?

R: Es la manera de copiar una lista en Python. Se usa la sintaxis [:] para obtener desde el primer elemento hasta el último.