Python

Una primera aplicación en Django

Posted on 7 min read 18 views

El primer concepto a tener en cuenta al crear una aplicación web en Django es el de vista (view). Una vista es una página web de la aplicación con una función específica y que emplea un determinado diseño.

En Django cada vista es representada por una función o método en Python. Dicha vista se selecciona a partir de la URL que se demande.

Primera página en Django

En primer lugar debemos acceder al archivo views.py donde escribiremos el siguiente código Python:

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world.")

De este modo hemos definido la página en Django. Ahora falta asociarla con una URL. Para ello creamos, dentro del directorio de la aplicación, un archivo urls.py que se incluirá el siguiente código:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
]

Y a continuación incluimos la raíz del módulo de la aplicación dentro de las URLs del sitio. Para ello editamos el archivo urls.py que se creó en su momento en la raíz del sitio (no confundir la raíz del sitio con la raíz de la aplicación). Dicho archivo incluirá el siguiente código:

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^polls/', include('polls.urls')),
    url(r'^admin/', include(admin.site.urls)),
]

En la vista local http://127.0.0.1:8000/polls/ veremos ahora el texto “Hello, world.”.

Argumentos de la función url()

La función urls() tiene 4 argumentos:

  • regex
  • view
  • kwargs
  • name

Los dos primeros son obligatorios y los dos últimos opcionales.

El primer argumento regex es una abreviatura de regular expression, que son patrones sintácticos aplicados en este caso a las URL. En el caso de la URL  http://www.example.com/myapp/?page=3 Django buscará myapp/.

Una vez que Django encuentra una coincidencia con la expresión regular regex, entonces llama a la función especificada en el argumento view mediante el objeto HttpRequest.

El argumento  kwargs envía palabras clave (keywords) que son pasadas en un diccionario a la función especificada en view.

El último argumento name permite nombrar sin ambigüedad las URLs de modo que pueden establecerse cambios en el esquema de URLs del sitio manejando sólo un archivo.

Añadiendo más páginas o vistas

Para añadir nuevas vistas editamos el archivo views.py dentro de la aplicación:

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

Las funciones detail, results y vote son las que definen las nuevas vistas, que a su vez deben incluirse en el archivo de URLs urls.py mediante llamadas de la función url():

from django.conf.urls import url

from . import views

urlpatterns = [
    # ex: /polls/
    url(r'^$', views.index, name='index'),
    # ex: /polls/5/
    url(r'^(?P[0-9]+)/$', views.detail, name='detail'),
    # ex: /polls/5/results/
    url(r'^(?P[0-9]+)/results/$', views.results, name='results'),
    # ex: /polls/5/vote/
    url(r'^(?P[0-9]+)/vote/$', views.vote, name='vote'),
]

Si llamamos a la siguiente URL en el navegador http://127.0.0.1:8000/polls/34/ Django buscará en urlpatterns la expresión regular que primero concuerde con dicha URL. En este caso será la llamada al método detail() que precisa del argumento question_id, el cual se pasa a través de la URL.

Cuando alguien solicita la página /polls/34/, Django carga el módulo mysite.urls, según lo establecido en el parámetro ROOT_URLCONF de la configuración. Allí encuentra la variable urlpatterns y en ella ‘^polls/’ como expresión regular asociada a include(‘polls.urls’) que hace que se procese a su vez el módulo polls.urls con la parte restante de la URL (“34/”), que concuerda con r’^(?P<question_id>[0-9]+)/$’, resultando en una llamada a la vista detail():

detail(request=<HttpRequest object>, question_id='34')

Vistas que realizan funciones

Una vista puede hacer cualquier cosa que deseemos usando Python. Puede extraer o escribir datos de una base de datos, generar un archivo PDF o ZIP o presentar información usando una plantilla.

En el post acerca de los primeros pasos en Django empleamos la base de datos que trae el sistema por defecto. A continuación modificaremos el código de la vista index en el archivo views.py para mostrar contenidos de esa base de datos, concretamente los 5 últimos resultados de la encuesta:

from django.http import HttpResponse

from .models import Question

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    output = ', '.join([p.question_text for p in latest_question_list])
    return HttpResponse(output)

Por el momento no se ha añadido ningún tipo de diseño a la página. Mediante el sistema de plantillas de Django es posible separar el diseño del código Python. Para ello, un primer paso es crear un directorio de plantillas llamado templates en el directorio de la aplicación. Django buscará en dicho directorio por la plantilla que corresponda a una determinada vista. Dentro de este directorio crear otro que se llame polls y dentro de este un archivo llamado index.html de modo que la plantilla se encontrará en polls/templates/polls/index.html. Dentro de Django nos referiremos a esta plantilla como polls/index.html.

Dentro del archivo index.html incluiremos el siguiente código.

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

Ahora actualizamos la vista index en polls/views.py para usar la plantilla:

from django.http import HttpResponse
from django.template import RequestContext, loader

from .models import Question

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')
    context = RequestContext(request, {
        'latest_question_list': latest_question_list,
    })
    return HttpResponse(template.render(context))

Este código carga la plantilla y le pasa un contexto, el cual es una diccionario que establece la relación entre los nombres de las variables en la plantilla con los objetos Python.

Si cargamos de nuevo la página, veremos que ahora aparece la estructura de lista que hemos indicado en la plantilla.

Aún puede simplificarse más mediante la función render() de Python, que evita importar loader y RequestContext; incluso no sería necesario importar HttpResponse si no se utilizase por otras funciones. Empleando render() la vista index() puede reescribirse del siguiente modo:

from django.shortcuts import render

from .models import Question

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

La función render() toma el objeto request como primer argumento, seguido del nombre de la plantilla como segundo argumento y un diccionario como tercer argumento, devolviendo un objeto HttpResponse de la plantilla especificada con el contexto indicado.

Así mismo, puede simplificarse la forma de escribir las URLs en el archivo index.html:

{% if latest_question_list %}
 <ul>
 {% for question in latest_question_list %}
 <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
 {% endfor %}
 </ul>
{% else %}
 <p>No polls are available.</p>
{% endif %}

Como puede verse, se ha sustituido  href=“/polls/{{ question.id }}/”  por  href=”{% url ‘polls:detail’ question.id %}” empleando el argumento name para referirnos a la URL, de acuerdo a como está especificado en el archivo url.py.

Escribimos polls:detail para referirnos a la función detail que se encuentra en polls/urls.py distinta de la que podría encontrase en admin/urls.py. Ambas están especificadas en mysite/urls.py :

urlpatterns = [
 url(r'^polls/', include('polls.urls')), 
 url(r'^admin/', include(admin.site.urls)),
]

Incluir la página de error 404

La página muestra una serie de enlaces que nos llevan a la vista detail correspondiente. En caso de que por cualquier razón dicha vista no existiese, debería aparecer una nueva plantilla indicando que se ha producido un error 404 de página no encontrada. Para ello, debe modificarse la función asociada a la vista detail añadiendo el siguiente código:

from django.shortcuts import render
from django.http import HttpResponse
from django.http import Http404
from .models import Question

# ...

def detail(request, question_id):
    try:
        question = Question.objects.get(pk=question_id)
    except Question.DoesNotExist:
        raise Http404("Question does not exist")
    return render(request, 'polls/detail.html', {'question': question})

donde se ha cargado Http404 y se llama a la plantilla detail.html.

Existe otra forma de llamar a la plantilla 404 mediante el método get_object_or_404

from django.shortcuts import get_object_or_404, render

from .models import Question
# ...
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

La función get_object_or_404() tiene como primer argumento el modelo de Django, seguido de un número arbitrario de argumentos o palabras clave, que son enviados a dicho modelo, dando lugar a una página 404 si el modelo no existe.

En cuanto a la plantilla detail.html puede ser un archivo con el siguiente contenido:

<h1>{{ question.question_text }}</h1>
<ul>{% for choice in question.choice_set.all %}
 <li>{{ choice.choice_text }}</li>
</ul>
{% endfor %}

La etiqueta h1 muestra el elemento question_text del objeto question. Django buscará si se trata de un diccionario, un atributo o una lista, en ese orden. En este caso se trata de un atributo, como podemos ver en la clase Question del archivo models.py.

En el bucle for llama a todos los elementos de choice que contienen el índice dado por question y presenta el valor de choice_text para cada uno de ellos.

 

El administrador de Django

Posted on 2 min read 19 views

El administrador de Django es creado por defecto por el sistema y permite añadir, modificar o eliminar las entradas en la base de datos. Es un administrador escrito únicamente para el uso de los administradores del sitio con una interface clara y de fácil manejo.

Creación del super usuario

El primer paso es crear un usuario y contraseña:

iMac27:mysite JMG$ python manage.py createsuperuser
Username (leave blank to use 'jmg'): admin
Email address: myemail@domain.com
Password: 
Password (again): 
Superuser created successfully.

Inicialización del servidor

A continuación activamos el servidor de desarrollo:

$ python manage.py runserver

y vemos el aspecto del administrador en http://127.0.0.1:8000/admin/.

Manejar los objetos de una aplicación desde el administrador

Para ello debe modificarse el archivo admin.py en la carpeta de la aplicación. En el caso del ejemplo básico descrito en una entrada previa, añadimos las líneas correspondientes a dicho archivo:

from django.contrib import admin
from .models import Question
admin.site.register(Question)

Como vemos, se ha importado el modelo Question y se ha asociado con el administrador. Recargando la página, vemos como una nueva “tabla” aparece.

Añadir objetos relacionados

Anteriormente hemos habilitado el modo en que el modelo Question era accesible desde el administrador. Ahora bien, cada objeto Question tiene asociado un objeto Choice. Es decir, son dos tablas que están relacionadas. Las formas de relacionarlas en Django se obtiene creando nuevos modelos (clases) que definan dicha relación. El archivo admin.py tendrá ahora el siguiente código:

from django.contrib import admin
from .models import Question, Choice
class ChoiceInline(admin.TabularInline):
 model = Choice
 extra = 3

class QuestionAdmin(admin.ModelAdmin):
 fieldsets = [
 (None, {'fields': ['question_text']}),
 ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
 ]
 inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)

El administrador puede customizarse en gran medida y adaptarse a cualquiera de nuestras necesidades. Pero dado de que solo queremos hacer ahora una primera aproximación, lo vamos a dejar aquí por el momento.

Django en Mac OS X. Primeros pasos

Posted on 8 min read 239 views

Instalación de Django

Debemos tener instalado pip en Mac OS X, el cual se instala junto con Homebrew. En ese caso, instalar Django es tan sencillo como escribir la siguiente sentencia en el terminal:

$ sudo pip install Django

Después de introducir la password, se realizará la instalación que terminara con el mensaje siguiente:

Successfully installed Django-1.8.4

Otra posibilidad es emplear la siguiente expresión en la línea de comandos:

$ sudo easy_install django

tras la que aparece el siguiente mensaje al finalizar la instalación:

Finished processing dependencies for django

En cualquier caso, podemos comprobar la versión instalada mediante la siguiente sentencia en el terminal:

$ python -c "import django; print(django.get_version())"

Creación del proyecto

Para inicializar el proyecto mysite con los elementos necesarios, nos situamos en el directorio donde queremos crear el proyecto y escribimos la siguiente sentencia:

$ django-admin startproject mysite

Para los que se inician en Python a partir de PHP se debe considerar una diferencia importante respecto al lugar donde ubicaremos el código. En PHP normalmente se coloca en la carpeta raiz el servidor /public_html/ o similar. En Django se mejora la seguridad guardando el código fuera de la raíz pública.

La sentencia anterior crea una carpeta mysite con el siguiente contenido:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

Veamos que es cada uno de estos archivos:

  • manage.py: incluye las funciones para administrar el proyecto desde la línea de comandos (referencia completa).
  • mysite/ : es el directorio donde se encuentra el proyecto y su nombre será el empleado para realizar cualquier importación al mismo (ej. mysite.urls).
  • mysite/__init__.py: este archivo no tiene contenido y cumple la función de indicar a Python que el directorio donde se encuentra es un paquete Python.
  • mysite/settings.py: contiene la configuración del proyecto y tiene todas las características de un módulo Python.
  • mysite/urls.py: en este módulo se declaran todas las URLs del proyecto y viene a ser un mapa de contenidos del sitio.
  • mysite/wsgi.py: es el punto de entrada para los servidores WSGI, el estándar para Python.

Configuración de la base de datos

La configuración de la base de datos se encuentra en el módulo settings.py. Por defecto, contiene la configuración de una base de datos SQLite, incluida en Python, adecuada para el aprendizaje pero no para proyectos reales. En este caso, los datos se guardaran en un simple fichero en el directorio del proyecto. Los parámetros que definen la base de datos se encuentran en el siguiente diccionario:

DATABASES = {
	'default': {
		'ENGINE': 'django.db.backends.sqlite3',
		'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
	}
}

Para SQLite, ENGINE es django.db.backends.sqlite3. Si usamos una base de datos MySQL este parámetro será django.db.backends.mysql. Podemos encontrar parámetros análogos para PostgreSQL u Oracle.

NAME indica el nombre de la base de datos. En el caso de SQLite será el nombre del archivo, incluyendo la ruta completa en caso de que no se encuentre en el mismo directorio del proyecto.

En el caso de una base de datos MySQL en un servidor remoto debemos facilitar otra información dentro del diccionario como USER, PASSWORD, HOST y PORT.

DATABASES = {
	'default': {
		'ENGINE': 'django.db.backends.mysql',
		'NAME': 'mydatabase',
		'USER': 'mydatabaseuser',
		'PASSWORD': 'mypassword',
		'HOST': '127.0.0.1',
		'PORT': '5432',
	}
}

En settings.py podemos también encontrar la lista INSTALLED_APPS con todas las aplicaciones activas en el proyecto. Por defecto cualquier proyecto Django tiene las siguientes aplicaciones:

  • django.contrib.admin – El administrador.
  • django.contrib.auth – Sistema de autenticación.
  • django.contrib.contenttypes – Esquema de los tipos de contenido
  • django.contrib.sessions – Sistema de sesiones.
  • django.contrib.messages – Sistema de mensajes.
  • django.contrib.staticfiles – Sistema de manejo de archivos estáticos.

Cada una de estas aplicaciones requiere al menos una tabla en la base de datos, que deben crearse mediante el siguiente comando:

$ python manage.py migrate

El servidor de desarrollo

Django contiene un servidor web básico escrito en Python adecuado para las etapas de desarrollo previas a un trabajo en producción en un servidor Apache. Para verificar que dicho servidor funciona, debemos ejecutar el siguinte comandodesde el directorio mysite:

$ python manage.py runserver

Si todo funciona correctamente veremos la siguiente respuesta en la línea de comandos:

Performing system checks...

0 errors found
September 15, 2015 - 15:50:53
Django version 1.8, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Así mismo, abriendo en el navegador la URL http://127.0.0.1:8000/ veremos el resultado.

Creación de una aplicación

Dentro de un proyecto podemos encontrar diferentes aplicaciones (app) que realizan diferentes funciones dentro del mismo. Cada aplicación está contenida en una carpeta que Django crea al efecto. Las aplicaciones son exportables a otros proyectos.

Al crear una nueva aplicación, Django creará una nueva carpeta donde se encontrarán todos los archivos de la misma. En este ejemplo se creará una aplicación denominada polls (encuestas) en el directorio principal (cualquiera hubiese sido válido) mediante la siguiente sentencia:

$ python manage.py startapp polls

El contenido de la carpeta polls será el siguiente:

polls/
    __init__.py
    admin.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py

El primer paso es definir los modelos que se guardarán en el archivo models.py. Dichos modelos contienen la estructura de la base de datos y algunos metadatos.

En nuestra aplicación para realizar encuestas crearemos dos modelos: Question (pregunta) y Choice (selección). Cada modelo equivale a una tabla que está representada por una clase que a su vez es una subclase de django.db.models.Model. La clase (tabla) Question tendrá dos variables (campos), la pregunta y la fecha de publicación, que equivalen a campos de la tabla. La clase (tabla) Choice tendrá tres variables (campos): un índice que le relaciona con la pregunta, un texto y los votos que ha recibido. El archivo models.py que contiene los modelos contendrá lo siguiente:

from django.db import models

class Question(models.Model):
        question_text = models.CharField(max_length=200)
        pub_date = models.DateTimeField('date published')

class Choice(models.Model):
        question = models.ForeignKey(Question)
        choice_text = models.CharField(max_length=200)
        votes = models.IntegerField(default=0)

Vemos que cada campo se representa por una instancia de la clase Field, como son CharField para campos de caracteres o  DateTimeField para fechas. De este modo Django conoce el tipo de dato que se aloja en cada campo.

Algunas clases precisan argumentos obligatorios, como es el caso de CharField en el ejemplo, que requiere el argumento max_length, y pueden tener también argumentos opcionales.

Activación de la aplicación

El primer paso es editar el fichero settings.py para incluir la nueva aplicación dentro de la lista INSTALLED_APPS :

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',
)

A continuación debe ejecutarse el comando makemigrations para crear una migración, informando a Django de que se han realizado cambios en los modelos, en este caso añadiendo la aplicación poll. La línea de comandos sería la siguiente:

$ python manage.py makemigrations polls

El resultado será el siguiente:

Migrations for 'polls':
  0001_initial.py:
    - Create model Question
    - Create model Choice
    - Add field question to choice

Las migraciones son archivos donde se guardan los cambios a realizar. Con el comando makemigrations hemos creado la migración, pero no la hemos realizado. Para ello debe ejecutarse el comando migrate propiamente dicho:

$ python manage.py migrate

En la consola veremos las operaciones que se van realizando, que serán todas las migraciones que no se hayan realizado hasta el momento, de acuerdo a la información almacenada por Django en la tabla django_migrations.

Primeras pruebas con la API

Django proporciona una API gratuito al que podemos acceder desde el Python shell. El primer paso es invocar el shell:

$ python manage.py shell

Se incluye  manage.py para indicar a Django la ruta al archivo mysite/settings.py.

Una vez en el  shell , importamos las clases Question, Choice:

>>> from polls.models import Question, Choice

Podemos comprobar que todavía no se ha creado ningún objeto de la clase Question:

>>> Question.objects.all()

El resultado será vacío:

[]

A continuación creamos un nuevo elemento de la tabla y lo salvamos. Dado que la variable pub_date requiere la fecha y hora  actual, vamos a escribir dicho valor de acuerdo a la zona horaria. Para ello primeramente importamos la clase preinstalada timezone incluida en utils:

>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save()

Automáticamente se le ha asignado un ID que podemos visualizar:

>>> q.id
1

Puede accederse a los campos:

>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

Ahora que ya tenemos un registro en Question podemos volver a probar Question.objects.all(). El resultado ahora es:

>>> Question.objects.all()
[]

el cual indica que no está vacío pero nos da muy poca información acerca del registro. Para ello añadimos __str__() (Python 3) o __unicode__ (Python 2) a los modelos Question y Choice:

from django.db import models

class Question(models.Model):
    # ...
    def __unicode__(self):
        return self.question_text

class Choice(models.Model):
    # ...
    def __unicode__(self):
        return self.choice_text

Después de guardar este cambio, volvemos a inicializar el shell:

$ python manage.py shell

Y cargamos de nuevo los modelos:

>>> from polls.models import Question, Choice

Ahora encontramos:

>>> Question.objects.all()
[<Question: What's new?>]

Para modificar la variable:

>>> q.question_text = "What's up?"
>>> q.save()

La API de Django permite obtener información de la base de datos mediante una serie de funciones a partir de argumentos:

>>> Question.objects.filter(id=1)
[<Question: What's up?>]
>>> Question.objects.filter(question_text__startswith='What')
[<Question: What's up?>]

>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

La referencia completa de todas las funciones de la API para acceso a la base de datos puede encontrarse en la documentación de Django.

Esta guía nos da una pequeña muestra de las posibilidades de Django a través de la consola.

Clases en Python

Posted on 5 min read 22 views

¿Qué es una clase?

Podemos decir que una clase es un objeto definido por el usuario en el que se definen una serie de atributos para cada cualquier objeto dentro de la misma. Los atributos son datos, instancias o variables y métodos. De forma llana, podemos decir que una clase en un lugar donde almacenar métodos, junto con variables u otros elementos, accesibles todos ellos dentro de un mismo código. Llamando a este código o clase tendremos acceso a todos esos elementos con una sola llamada. Una clase puede ser llamada desde diferentes lugares y ejecutarse de forma simultánea sin ningún conflicto, mientras que si se hiciese mediante funciones definidas por el usuario si podría darse ese conflicto.

Hagamos ahora un repaso a los términos empleados en relación a las clases:

  • Variable de clase. Una variable dentro de una clase es una variable a la que tienen acceso todas las instancias de la clase.
  • Variable de dato. Es una variable de clase asociada a los objetos de la clase.
  • Variable de instancia. Es una variable definida dentro de un método y que tiene valor solamente dentro de dicho instancia de la clase. Viene a ser una variable local.
  • Herencia. Es la transferencia de ciertas características de una clase a otra clase derivada a partir de ella. Por ejemplo, pensemos en una clase “animales” con todas las características comunes de diferentes animales y después otras clases derivadas de ellas como pueden ser “perros” y “gatos“que comparten las características de la clase animales pero tiene además ciertas características propias.
  • Instancia. Es cualquier objeto individual dentro de una clase. Por ejemplo, si tenemos cuatro gatos, cada uno con un nombre, y les llamamos usando la clase gatos, el nombre de cada uno de ellos sería una instancia de la clase.
  • Inicialización. Es el proceso de llamar a la clase. Es posible que nada más iniciar la clase se ejecuten ciertos métodos o se establezca el valor de ciertas variables.
  • Método. Es una función definida dentro de una clase. Es, por tanto, una función dentro de una clase.
  • Objeto. Es una instancia única dentro de la estructura de datos de una clase. Comprende tanto las variables de clase, como las variables de instancia o los propios métodos.

Veamos un primer ejemplo:

class Person:
    def __init__(self,gender,name):
        self.gender = gender
        self.name = name
    def display(self,value):
        print "You're a ",self.gender, ", and your name is ",self.name, " and look at this value: ", value
    
people1 = Person("male","Jose Manuel")
people2 = Person ("female", "Ana")
people1.display(33)
people2.display(22)

Debemos observar lo siguiente:

  • La clase se define mediate class seguido por el nombre de la clase y dos puntos, como en cualquier función.
  • Se define un primer método __init__ (función pre construida en Python) donde se va a pasar dos variables gendername que llegan a la clase cuando esta es iniciada. Estas entradas se asocian ahora con el objeto self y se usan en el resto de la clase. No es obligatorio llamar a este método en primer lugar, pero es interesante desde que nos permite tener asignados los valores de ciertas variables dentro de toda la clase.
  • Un segundo método display tiene como entradas self, definido anteriormente. Este método simplemente escribe una frase empleando estas dos variables, en este caso.
  • Una vez definida la clase, puede iniciarse en cualquier lugar del código.
  • Para iniciar la clase Person se le pasan los dos valores que precisa esta clase y se asigna a las variables people1people2. De este modo podremos llamar a los métodos de la clase Person a través de estas variables, cada una de las cuales son ahora dos instancia u objetos de la clase Person.
  • Una vez iniciada la clase, puede llamarse a cualquiera de sus métodos. Vemos que en la llamada al método display le estamos pasando externamente el valor que queremos que tome la variable value en esta llamada al método.

Es posible pasar a la clase un diccionario o una tupla de cualquier tamaño. En el siguiente ejemplo estamos pasando un diccionario, indicado por el doble asterisco (**). Si fuese una tupla emplearíamos un solo asterisco (*).

class Example:
    def __init__(self,**dictionary):
        self.variables = dictionary
    def set_vars(self,k,v):
        self.variables[k] = v
    def get_vars(self,k):
        return self.variables.get(k)
    
var = Example(Edad=18,Nombre="Ana")
var.set_vars('talla','36')
print var.get_vars('talla')
print var.get_vars('Edad'), var.get_vars('Nombre')

Podemos ver como al crear la instancia var para la clase Example estamos pasando un diccionario (indice,valor). El método set_vars puede recibir las variables mediante self (por defecto) o hacerlas llegar al llamar al método. En cualquier caso, lo que enviamos son siemrpe dos parámetos que se entenderán como índice (key, k) y valor (value, v).

Por último, veamos el concepto de herencia con un ejemplo:

class Animals:
    def eat(self):
        print 'I can eat'
    def talk(self):
        print 'I can talk'

class Cats(Animals):
    def talk(self):
        print 'Meow'
    def move(self):
        print 'I can move'

class Dogs (Animals):
    pass
        
animal_1 = Cats()
animal_2 = Dogs()

animal_1.talk()
animal_2.talk()
animal_1.eat()
animal_2.eat()

En primer lugar, hemos creado la clase Animals con los métodos  eattalk. A continuación creamos la clase  Cats que hereda los métodos de Animals al escribir el nombre de esta clase entre los paréntesis de definición de la primera. Sin embargo, el método talk se define de nuevo en Cats con lo que tendrá prioridad en cualquier instancia de la clase Cats. Al definir la clase Dogs, simplemente escribimos pass, lo cual quiere decir que hereda todos los métodos y resto de objetos de la clase padre.

Esto es todo por ahora respecto a las clases en Python. Continuaremos con otros aspectos en este repaso en próximos posts.

Manejo de ficheros en Python

Posted on 3 min read 33 views

Abrir un fichero y leer su contenido es muy sencillo en Python. Veamos un primer ejemplo en que queremos leer un fichero de texto (.txt) localizado en el mismo directorio que el archivo Python (.py) a ejcecutar:

file = open('example.txt')
for line in file:
    print line,

La función open abre el fichero. Posteriormente recorremos las líneas del archivo de texto e imprimimos cada una de ellas, haciéndolas terminar, en este caso, sin ningún carácter.

Debe notarse la coma (,) en la sentencia print. Esto hace que se concluya la línea con un espacio en lugar de con un salto de línea. Es un comando propio de Python 2.x, que se realiza de otro modo en Python 3.x (no abordamos aquí sentencias en Python 3.x).

Podemos especificar que se trata de la lectura de un archivo añadiendo un segundo argumento a la función open:

file = open('example.txt', 'r')

donde r viene de read.  Cuando se trate de abrir un archivo para la escritura, el segundo argumento será w, de write, y cuando se trate de añadir nuevo contenido a un fichero ya existente se utilizará a, de append.

En el siguiente ejemplo vamos a abrir un archivo, leer su contenido y escribir dicho contenido en un nuevo archivo de texto:

input = open('old.txt','r')
output = open('new.txt','w')
for line in input:
    print >> output, line,

donde r viene de read.

Lo anterior es válido para ficheros de texto con un número pequeño de líneas. Para ficheros grandes el procedimiento de leer línea por línea el fichero no es operativo. Para ello debe establecerse el tamaño de un buffer de modo podamos procesar ese tamaño de información cada vez, en lugar de línea por línea. En el siguiente código establecemos el tamaño de la información a procesar (buffersize) y leemos el archivo original en secciones de ese tamaño (input.read(buffersize)). Posteriormente vamos escribiendo dichas secciones una a una en el archivo destino (output.write(buffer)) hasta llegar a un máximo para el tamaño del archivo destino (bufferlimit). En pantalla escribimos un indicador de cada paso del proceso (print”&”,).

buffersize = 100000
input = open('bigfile.txt', 'r')
output = open('newbigfile.txt', 'w')
buffer = input.read(buffersize)
bufferlimit = 1000000

while bufferlimit >0:
    output.write(buffer)
    bufferlimit = bufferlimit - buffersize
    print "&",

El mismo proceso puede realizarse sin límite en el tamaño del archivo final. En este caso la condición del bucle es len(buffer), es decir el tamaño del fichero leído y escrito en bloques de tamaño buffersize).

buffersize = 10000
input = open('bigfile.txt', 'r')
output = open('newbigfile.txt', 'w')
buffer = input.read(buffersize)

while len(buffer):
    output.write(buffer)
    print ".",
    buffer = input.read(buffersize)

Además de contenidos alfanuméricos, es posible tratar archivos con cualquier código binario, ya sean archivos de vídeo, imágenes o cualquier otra información. A continuación presentamos un ejemplo en el que leemos y escribimos una imagen. Establecemos la variable buffersize del tamaño en bits de cada paso del proceso. Al abrir los archivos de entrada y de salida especificamos que son archivos binarios mediante rb (read binary) y wb (write binary). El resto es como cualquier otro archivo.

buffersize = 10000
input = open('image_test.jpg', 'rb')
output = open('new_image_test.jpg', 'wb')
buffer = input.read(buffersize)

while len(buffer):
    output.write(buffer)
    print ".",
    buffer = input.read(buffersize)

Funciones en Python

Posted on 1 min read 16 views

Funciones de usuario

Estas son las funciones creadas por el usuario y que no están predefinidas en Python. La ventaja de las funciones es que las escribimos una vez y podemos usarlas tantas veces como deseemos.

La sintaxis básica de una función es la siguiente:

def function_name():
    string ='Hello'
    return string

print (function_name())

Dentro de la función pueden realizarse las operaciones que se deseen.

A la función se le pueden pasar tantos parámetros, separados por comas, como se deseen:

mylist = [1,2,3,4,5]
def my_function_name(list):
    list.append(6)
    return list

print (my_function_name(mylist))

otherlist = [7,8,9,10]

def other_function_name(list1,list2):
    list1.extend(list2)
    return list1

print(other_function_name(mylist,otherlist))