viernes, 23 de noviembre de 2012

Ficheros de datos en paquete Python

Estructura para un proyecto de python, con algunos archivos de datos necesarios para la aplicación:
Para que todos los ficheros de datos se añadan al paquete de python és necesario indicar en el setup.py que deseamos añadir estos. Teniendo en cuenta una distribución de los directorios como la anterior, el programa setup.py quedaría de la siguiente manera:

#!/usr/bin/python

from setuptools import setup, find_packages
setup(
 name='mypkg',
 version='0.0.2',
 author='Miquel Perello Nieto',
 author_email='perello.nieto@gmail.com',
 url='perellonieto.com',
 packages = find_packages('src'),  # include all packages under src
 package_dir = {'':'src'},   # tell distutils packages are under src

 package_data = {
  # If any package contains *.txt files, include them:
  '': ['*.txt'],
  # And include any *.dat files found in the 'data' subdirectory
  # of the 'mypkg' package, also:
  'mypkg': ['data/*.dat'],
  }
    )



Resolviendo dependencias circulares en c++ con forward declaration

El problema de las dependencias circulares aparece en el momento en que dos clases distintas tienen una instancia o hacen referencia a la otra en su declaración.

Como ejemplo estas dos clases, las cuales tienen un puntero a una instancia de la otra:

class_a.h

#ifndef CLASS_A_H_
#define CLASS_A_H_

#include "class_b.h"

class ClassB; // Commenting this line compilation will fail

class ClassA
{
public:
 ClassA();

private:
 ClassB * b;
};

class_b.h

#ifndef CLASS_B_H_
#define CLASS_B_H_

#include "class_a.h"

class ClassA; // Commenting this line compilation will fail

class ClassB
{
public:
 ClassB();

private:
 ClassA * a;
};

En este caso hasta que una de las clases no haya sido totalmente interpretada por el compilador, éste no podrá interpretar la otra. Lo que hace que el compilador se queje de no conocer el objeto.

Para solucionar este problema se debe indicar al compilador en ClassB que ClassA es una clase, y lo mismo para la ClassA. A esta declaración "anticipada" se la llama "Forward declaration" (ver Wikipedia: Forward declaration).

En el código de arriba este problema está solucionado, pero si quereis reproducir el error comentar la linia que esta indicada.

Aqui teneis el resto de ficheros necesarios para hacer una prueba:

main.cpp

#include "class_a.h"
#include "class_b.h"

int main()
{
 ClassA a;
 ClassB b;

 return 0;
}

class_a.cpp

#include "class_a.h"
#include "cstdio"

ClassA::ClassA() {
 printf("Creating ClassA object\n");
}

class_b.cpp

#include "class_b.h"
#include "cstdio"

ClassB::ClassB() {
 printf("Creating ClassB object\n");
}

Para compilarlo todo:

Makefile

all: main

main: main.o class_a.o class_b.o
 g++ -o main main.o class_a.o class_b.o

main.o: main.cpp
 g++ -c main.cpp

class_a.o: class_a.cpp
 g++ -c class_a.cpp
 
class_b.o: class_b.cpp
 g++ -c class_b.cpp

clean: 
 rm -f *.o main

Ver explicación más detallada en la fuente : Stackoverflow