2017-05-18 1 views
0

J'ai trois questions, mais liées, et je ne comprends pas comment je peux les séparer. J'ai trouvé beaucoup d'informations sur ces questions, comme submodule extension, hierarchy, sur un empty __init__.py file, et comment cythonize multiple pyx files. Mais quand je les essaie ensemble, je ne peux pas les faire fonctionner.comment préparer des sous-modules de cythons

J'ai préparé un small repo en pensant ensemble des exemples de problèmes résolus. J'ai vérifié même le code de certains des projects listed qui utilisent le cython, mais qui n'obtiennent toujours pas comment faire trois choses en même temps.

  • vide __init__.py fichier:

Dans un projet (où tous les fichiers sont ciboire (et PXD ifneedbe)), avec un ciboire __init __ qui comprend. tous, quand il y a un fichier __init__.py, puis l'importer ne charge pas le ".so" mais l'init vide.

  • cythonize plusieurs fichiers:

Quand au lieu de préparer un __init__.py qui comprend tous les éléments d'un module. Comme:

cythonize(['factory.pyx', 'version.pyx']) 

résultant ".donc" importation soulève une exception:

>>> import barfoo 
(...) 
ImportError: dynamic module does not define init function (PyInit_barfoo) 

Il serait lié à la question précédente, s'il est nécessaire d'écrire quelque chose dans __init__.py .

  • Submodule:

En fait, c'est la question principale. Le singleton.pyx ferait partie d'un sous-module, disons utilise pour être utilisé à partir d'autres éléments du module.

Pour l'échantillon y est un sous-module (simplement appelé soum) ajoutée dans le setup.py comme un autre poste. J'ai placé plus tôt que le principal (je ne sais pas si cela fait vraiment une différence, je ne l'ai pas vu).

>>> import barfoo 
>>> import barfoo.subm 
(...) 
ImportError: No module named 'barfoo.subm' 

Séparément, ces recettes fonctionnent, mais ensemble je ne peux pas. Le "__init__.py" semble être nécessaire quand il y a un mélange de "py" et "pyx". Les exemples expliquent comment cytoniser avec plusieurs fichiers, mais n'incluent pas le dernier point clé pour l'importation. Et les sous-modules ne sont pas complets sur la façon dont ils peuvent être importés d'un endroit ou d'un autre (importer des sous-modules lors de l'importation de la base, ou des importations facultatives lorsqu'elles sont spécifiées).

+1

Pouvez-vous décrire la disposition de votre fichier (avant et après la compilation)? Je ne suis pas 100% clair de la question mais je pense que vous essayez de compiler plusieurs fichiers .pyx dans un seul fichier .so, et cela ne fonctionne pas. Chaque fichier .pyx doit générer son propre fichier .so – DavidW

Répondre

0

Grâce aux commentaires de oz1 et DavidW, j'ai le solution. Oui, ces trois choses se rejoignent.

  • Très important est l'ordre lorsque l'importation dans le setup.py. Même le PEP8 est-ce que fait et je suis généralement pas dire que les importations devraient être classés par ordre alphabétique, il y a d'autres lignes de guidage (comme reddit « s):

Lorsque l'importation première cythonize puis configuration , provoquera que lorsque cythonize (find_pyx()) est appelé, le résultat sera une liste de distutils.extension.Extension objets.

from setuptools import setup, find_packages 
from Cython.Build import cythonize 

setuptools doivent être importés avant cython puis le résultat de cythionize() sera une liste des objets setuptools.extension.Extension qui peuvent être transmis à la configuration () appel.

  • Il est important de comprendre la signification des __init__ « s:.

Tous les __init __ ciboire fichiers avec inclut a été supprimé et chaque fichier .pxy produit ses propres .so binaire.

Le module principal et les sous-modules existeront tant que leurs répertoires contiennent le fichier __init__.py comme s'il s'agissait d'un code python pur.

Dans l'exemple que j'ai lié, le fichier barfoo/__ init__.py n'est pas vide parce que je veux que importation barfoo donne accès aux éléments comme version() ou Factory(). Ensuite, ce __init__.py est qui les importe comme un python pur normal.

  • Pour le sous-module:

similaires pour la et sous-module son propre fichier __init__.py. Dans cet exemple, le barfoo d'importation fera une de l'usine d'importation .factory, qui appellera de Bar import barfoo.subm, le soum sera disponible.

Mais si le sous-module n'est pas importé de cette manière secondaire, l'utilisateur y aura accès avec des appels tels que import barfoo.subm.

1

Hier soir, j'ai vu votre question, et fait un exemple simple selon le wiki. Mais cette question a été supprimée rapidement.

Voici l'exemple: https://github.com/justou/cython_package_demo

Assurez-vous que les paramètres du compilateur C et l'environnement python est correct, compiler les fichiers ciboire par course:

python setup.py build_ext --inplace 

L'utilisation est le même que paquet python:

from dvedit.filters import flip, inverse, reverse 
flip.show()  # print: In flip call Core function 
inverse.show() # print: In inverse call Core function 
reverse.show() # print: In reverse call Core function 

BTW, il n'y a pas besoin de créer un __init__.pyx, vous pouvez faire les importings de ext_module dans le __init__.py fichier

+0

Après l'avoir posté hier, j'ai pensé faire une autre itération par moi-même et essayer de mieux l'écrire. Désolé et merci. – srgblnch

+0

@srgblnch Peu importe. Est-ce que cela résout votre problème? – oz1

+0

Presque, je pense que j'ai quelque chose. L'inplace a quitté le fichier so dans le répertoire dvedit, mais dans mon essai, il l'a laissé ci-dessous (où l'installation est). – srgblnch