2009-05-11 5 views
3

J'ai quelque chose comme ceci:Un module Python peut-il utiliser les importations d'un autre fichier?

# a.py 
import os 
class A: 
    ... 

# b.py 
import a 
class B(A): 
    ... 

Dans la classe B (b.py) Je voudrais pouvoir utiliser les modules importés dans a.py (os dans ce cas). Est-il possible d'obtenir ce comportement en Python ou dois-je importer les modules dans les deux fichiers?

Edit: Je ne m'inquiète pas des temps d'importation, mon problème est le fouillis visuel que le bloc d'importations met sur les fichiers. Je finis par avoir des choses comme ça dans chaque contrôleur (RequestHandler):

from django.utils import simplejson 
from google.appengine.ext import webapp 
from google.appengine.ext.webapp import template 
from google.appengine.ext import db 

C'est ce que je voudrais éviter.

Répondre

13

Oui, vous pouvez utiliser les importations en provenance de l'autre fichier en allant a.os. Cependant, la méthode pythonique consiste simplement à importer les modules dont vous avez besoin sans en faire une chaîne (ce qui peut conduire à des références circulaires).

Lorsque vous importez un module, le code est compilé et inséré dans un dictionnaire de noms -> objets de module. Le dictionnaire se trouve sur sys.modules. Lorsque vous réessayez d'importer le module, Python vérifie si le dictionnaire est déjà présent. Si c'est le cas, il vous renvoie l'objet module déjà compilé. Sinon, il va compiler le code et l'insérer dans sys.modules. Comme les dictionnaires sont implémentés en tant que tables de hachage, cette recherche est très rapide et prend un temps négligeable par rapport au risque de créer des références circulaires.

Modifier: Je ne suis pas inquiet au sujet des temps d'importation , mon problème est le fouillis visuel que le bloc des importations met sur les fichiers.

Si vous avez seulement environ 4 ou 5 importations comme ça, ce n'est pas trop d'encombrement. Rappelez-vous, "Explicite est mieux qu'implicite". Si cela vous dérange vraiment beaucoup, faites ceci:

<importheaders.py> 
from django.utils import simplejson 
from google.appengine.ext import webapp 
from google.appengine.ext.webapp import template 
from google.appengine.ext import db 


<mycontroller.py> 
from importheaders import * 
0

Vous devez l'importer séparément. Toutefois, si vous avez vraiment besoin de transférer certaines fonctionnalités, vous pouvez renvoyer un module à partir d'une fonction. Just:

import os 
def x: 
    return os 

Mais cela semble être une fonctionnalité de plugin - les objets + l'héritage résoudraient un peu mieux ce cas.

+0

Je ne comment voir l'héritage une partie ici aiderait. Si A est la superclasse de B et qu'ils ont tous les deux des méthodes qui ont besoin du même module à des fins différentes, je devrais finir par importer ce module dans les deux fichiers, ou du moins c'est ce que je comprends des réponses actuelles. –

+0

Ce que je voulais dire est -> Je ne suis pas sûr de ce que vous voulez utiliser les modules chargés, mais la question semble étrange. Si vous obtenez des informations que le module X importe les modules Y, Z, alors vous n'obtenez aucune information spéciale. Pourquoi vous en soucieriez-vous à l'exécution? Habituellement, vous vous intéressez à certaines fonctionnalités spécifiques qui sont encapsulées dans une fonction/classe qui se trouve dans le module X lui-même. Quoi qu'il en soit, sans préciser pourquoi vous posez la question, il est difficile de répondre avec quelque chose de mieux ... – viraptor

0

Il semble que vous souhaitiez utiliser python packages. Regardez dans ceux-ci.

1

Il vous suffit d'importer à nouveau les modules. Importer un module en python est une opération très légère. La première fois que vous importez un module, python charge le module et y exécute le code. Lors de toute importation ultérieure, vous obtiendrez simplement une référence au module déjà importé.

Vous pouvez vérifier vous-même, si vous aimez:

# module_a.py 
class A(object): 
    pass 

print 'A imported' 

# module_b.py 
import module_a 

class B(object): 
    pass 

print 'B imported' 

# at the interactive prompt 
>>> import module_a 
A imported 
>>> import module_a  # notice nothing prints out this time 
>>> import module_b  # notice we get the print from B, but not from A 
B imported 
>>> 
+0

Travailler avec Google App Engine Je me retrouve avec 5-6 importations par RequestHandler (contrôleur) donc je voudrais éviter cela si possible , c'est trop encombrant dans l'en-tête de chaque fichier. –

0

Yep. Une fois que vous avez importé un module, ce module devient une propriété du module en cours. Dans Django, par exemple, de nombreux paquets importent simplement le contenu d'autres modules. Par exemple, dans le cas de Django, par exemple. Les classes et les fonctions sont définies dans des fichiers séparés juste pour la séparation:

# django/db/models/fields/__init__.py 
class Field(object): 
    ... 
class TextField(Field): 
    ... 

# django/db/models/__init__.py 
from django.db.models.fields import * 

# mydjangoproject/myapp/models.py 
from django.db import models 
class MyModel(models.Model): 
    myfield = models.TextField(...) 
    .... 
0

D'abord, vous pouvez le raccourcir à:

from django.utils import simplejson 
from google.appengine.ext import webapp, db 
from webapp import template 

suppose Deuxièmement vous avez ces^importations my_module.py

En my_module2 .py vous pouvez faire:

de webapp d'importation my_module2.py, db, tempate

exemple:

In [5]: from my_module2 import MyMath2, MyMath 

In [6]: m2 = MyMath2() 

In [7]: m2.my_cos(3) 
Out[7]: 0.94398413915231416 

In [8]: m = MyMath() 

In [9]: m.my_sin(3) 
Out[9]: 0.32999082567378202 

où my_module2 est:

from my_module import math, MyMath 

class MyMath2(object): 

    the_meaning_of_life = 42 

    def my_cos(self, number): 
     return math.cos(number * 42) 

et my_module1 est:

import math 

class MyMath(object): 

    some_number = 42 

    def my_sin(self, num): 
     return math.sin(num * self.some_number) 

Cheers, Hope it helps ALEP

Questions connexes