2013-08-19 4 views
0

У меня есть проект, который выглядит так:NameError: глобальное имя 'MAGIC_PINK' не определен

PyBlob 
|- __init__ 
|- Actor 
|- Blob 
|- Bullet 
|- main 
|- Player 
|- Scene 
|- utils 
|- Zombie 

__init__.py

import sys, pygame, cmath 
from Actor import Actor 
from Blob import Blob 
from Bullet import Bullet 
from Player import Player 
from Scene import Scene 
from utils import * 
from Zombie import Zombie 

utils.py

MAGIC_PINK = (255, 0, 255) 

# plus a small handful of utility functions 

Blob .py

from PyBlob import * 
class Blob: 
    def __init__(self, radius, body_colour=(0,0,0), face_colour=(255,255,0)): 
     self.body = pygame.Surface((2*radius, 2*radius)) 
     self.face = pygame.Surface((2*radius, 2*radius)) 
     self.body.set_colorkey(MAGIC_PINK) 

     #rest of module omitted for brevity 

Это приводит к ошибке:

NameError: global name 'MAGIC_PINK' is not defined 

Импорт классов, кажется, работает хорошо, так ясно, что я делаю что-то не так с этой переменной MAGIC_PINK.

ответ

0

У вас есть круговой импорт. Python должен импортировать PyBlob.Blob для импорта PyBlob, и он должен from PyBlob import * импортировать PyBlob.Blob. Это проблема.

Когда Python пытается запустить from PyBlob import *, он обнаруживает, что PyBlob уже находится в середине процесса импорта. Он не может ждать, пока PyBlob будет готов, потому что PyBlob не будет готов, пока Blob не будет готов, а Blob нуждается в PyBlob. Таким образом, он предполагает, что PyBlob «достаточно готов» и использует его в своем текущем состоянии. К сожалению, PyBlob по-прежнему не хватает большинства вещей, которые он должен иметь, поэтому from PyBlob import * не берет большую часть материала, который должен был забрать.

Чтобы устранить эту проблему, переконфигурируйте свой код, чтобы остановить использование циклического импорта, и старайтесь избегать import *.

+0

Поскольку python JIT компилируется в байт-код, не должен ли компилятор разрешить это до выполнения? Это не проблема на других языках, например. Ява. –

+0

@BlaiddDrwg: Нет. Переменные, содержащиеся в модуле, неизвестны до выполнения; вы можете поместить 'if today_is_wednesday(): x = 3' в модуль, и он будет иметь переменную' x', если она будет загружена в среду. 'from foo import *' не изменяет правила поиска имени, чтобы смотреть в 'foo', если он не находит глобальное; он ищет все имена в 'foo', которые не начинаются с подчеркивания и присваивают свои текущие значения одинаковым именам в текущем пространстве имен. – user2357112

+1

В Java существует очень похожая проблема - не с циклическим импортом (потому что импорт в Java * делает * просто изменяют некоторые правила поиска имени времени компиляции), но с круговой загрузкой классов. Класс Java может выполнять [произвольный код при загрузке класса] (http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html), который может инициировать загрузку других классов. Если загрузка класса Foo запускает загрузку класса Bar, а панель загрузки запускает загрузку Foo, JVM отменяет рекурсивную загрузку Foo и использует ее полунагруженным. – user2357112

0

utils.MAGIC_PINK попробовать, вы должны указать, в каком файле имя адресован