Может ли модуль Python использовать импорт из другого файла? - PullRequest
3 голосов
/ 12 мая 2009

У меня есть что-то вроде этого:

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

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

В классе B (b.py) я хотел бы иметь возможность использовать модули, импортированные в a.py (в данном случае os). Можно ли добиться такого поведения в Python или я должен импортировать модули в обоих файлах?

Редактировать: меня не беспокоит время импорта, моя проблема - это визуальный беспорядок, который блок импорта помещает в файлы. Я получаю такие вещи в каждом контроллере (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

Вот чего я бы хотел избежать.

Ответы [ 6 ]

13 голосов
/ 12 мая 2009

Да, вы можете использовать импорт из другого файла, перейдя в .os.

Тем не менее, питонский способ - просто импортировать нужные вам модули, не создавая из них цепочку (что может привести к циклическим ссылкам).

При импорте модуля код компилируется и вставляется в словарь имен -> объекты модуля. Словарь находится по адресу sys.modules.

import sys
sys.modules

>>> pprint.pprint(sys.modules)
{'UserDict': <module 'UserDict' from 'C:\python26\lib\UserDict.pyc'>,
 '__builtin__': <module '__builtin__' (built-in)>,
 '__main__': <module '__main__' (built-in)>,
 '_abcoll': <module '_abcoll' from 'C:\python26\lib\_abcoll.pyc'>,
# the rest omitted for brevity

Когда вы попытаетесь импортировать модуль снова, Python проверит словарь, чтобы увидеть, есть ли он там. Если это так, он вернет вам уже скомпилированный объект модуля. В противном случае он скомпилирует код и вставит его в sys.modules.

Поскольку словари реализованы в виде хеш-таблиц, этот поиск выполняется очень быстро и занимает незначительное время по сравнению с риском создания круговых ссылок.

Редактировать: я не беспокоюсь об импорте раз моя проблема заключается в визуальном беспорядок, который ставит блок импорта на файлы.

Если у вас есть только 4 или 5 таких импортов, это не слишком беспорядок. Помните: «Явное лучше, чем неявное». Однако, если это действительно беспокоит вас, сделайте следующее:

<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 *
1 голос
/ 12 мая 2009

Просто снова импортируйте модули.

Импорт модуля в python - это очень легкая операция. При первом импорте модуля python загрузит модуль и выполнит в нем код. При любом последующем импорте вы просто получите ссылку на уже импортированный модуль.

Вы можете проверить это сами, если хотите:

# 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 голосов
/ 12 мая 2009

Сначала вы можете сократить его до:

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

Во-вторых, предположим, что у вас есть эти импорты в my_module.py

В my_module2.py вы можете сделать:

из my_module2.py импортировать webapp, db, tempate

пример:

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

где my_module2:

from my_module import math, MyMath

class MyMath2(object):

    the_meaning_of_life = 42

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

и my_module1:

import math

class MyMath(object):

    some_number = 42

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

Ура, Надеюсь, поможет AleP

0 голосов
/ 12 мая 2009

Да. После импорта модуля этот модуль становится свойством текущего модуля.

# a.py
class A(object):
    ...

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

Например, в Django многие пакеты просто импортируют содержимое других модулей. Классы и функции определены в отдельных файлах только для разделения:

# 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 голосов
/ 12 мая 2009

Похоже, вы хотите использовать пакеты Python . Посмотри на них.

0 голосов
/ 12 мая 2009

Вы должны импортировать его отдельно. Однако, если вам действительно нужно переслать некоторые функции, вы можете вернуть модуль из функции. Просто:

import os
def x:
   return os

Но это похоже на функциональность плагина - объекты + наследование решат этот случай немного лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...