2013-08-19 125 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 

斑點.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準備好,因爲在Blob準備就緒之前PyBlob將不會準備好,Blob需要PyBlob。因此,它假設PyBlob「足夠準備好」,並在當前狀態下使用它。不幸的是,PyBlob仍然缺少它應該擁有的大部分內容,所以from PyBlob import *沒有提到它應該提取的大部分內容。

要解決此問題,請重新組織代碼以停止使用循環導入,並儘量避免使用import *

+0

由於python JIT編譯爲字節碼,編譯器不應該在運行時解決這個問題嗎?這在其他語言中不是問題,例如Java的。 –

+0

@BlaiddDrwg:沒有。一個模塊包含的變量直到運行時纔會知道;你可以把'if today_is_wednesday():x = 3'放在一個模塊中,如果它在週三被加載,它將只有一個'x'變量。 '從foo導入*'不改變名稱查找規則以查找'foo',如果它沒有找到全局;它會查找'foo'中所有不以下劃線開頭的名稱,並將其當前值賦給當前名稱空間中的同名變量。 – user2357112

+1

在Java中有一個非常類似的問題 - 不是循環導入(因爲Java *中的導入*只是更改了一些編譯時名稱查找規則),而是使用循環類加載。 Java類可以[在類加載時執行任意代碼](http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html),它可以觸發加載其他類。如果加載Foo類觸發加載類Bar,並且加載Bar觸發加載Foo,則JVM將取消Foo的遞歸加載並將其用於半加載。 – user2357112

0

嘗試utils.MAGIC_PINK,你應該指出在哪個文件名稱是寫給

相關問題