Может кто-нибудь объяснить это неожиданное поведение импорта Python? - PullRequest
0 голосов
/ 27 октября 2009

Я столкнулся с некоторым поведением из Python 2.6.1, которое я не ожидал. Вот некоторый тривиальный код для воспроизведения проблемы:

---- ControlPointValue.py ------
class ControlPointValue:
   def __init__(self):
      pass

---- ControlPointValueSet.py ----
import ControlPointValue

---- main.py --------------------
from ControlPointValue import *
from ControlPointValueSet import *

val = ControlPointValue()

.... вот ошибка, которую я получаю при запуске main.py (под OS / X Snow Leopard, если это имеет значение):

jeremy-friesners-mac-pro-3:~ jaf$ python main.py 
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    val = ControlPointValue()
TypeError: 'module' object is not callable

Может кто-нибудь объяснить, что здесь происходит? Python запутывается, потому что имя класса совпадает с именем файла? Если да, то как лучше всего решить проблему? (Я бы предпочел, чтобы мои файлы Python были названы в честь классов, которые в них определены)

Спасибо, Джереми

Ответы [ 2 ]

11 голосов
/ 27 октября 2009

Не думаю, что это неожиданно. Что вы в основном делаете:

1) первый импорт в main.py импортирует содержимое модуля ControlPointValue в глобальное пространство имен. это создает класс, связанный с этим именем.

2) второй импорт в main.py импортирует содержимое модуля ControlPointValueSet в глобальное пространство имен. Этот модуль импортирует модуль ControlPointValue. Это перезаписывает привязку в глобальном пространстве имен, заменяя привязку для этого имени из класса в модуль.

Чтобы решить, я бы предложил вам не импортировать *, никогда. Всегда сохраняйте последний префикс модуля. Например, если у вас есть файл foo / bar / baz / bruf.py, содержащий класс Frobniz, выполните команду

from foo.bar.baz import bruf

и затем используйте bruf.Frobniz ()

4 голосов
/ 27 октября 2009

В дополнение к другим предложениям по импорту звездочек, не называйте ваш модуль и ваш класс одинаковыми. Следуйте указаниям pep8 и дайте вашим модулям короткие имена в нижнем регистре и назовите ваши классы LikeThis Э.Г.

---- controlpoints.py ------
class ControlPointValue:
   def __init__(self):
      pass

---- valuesets.py ----
from controlpoints import ControlPointValue

---- main.py --------------------
from controlpoints import ControlPointValue
from valuesets import *

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