2012-02-12 4 views
1

Я не буду публиковать код, я приведу только соответствующие разделы, так как он немного длинный.Проблема с импортом модуля Python

Итак, у меня есть файл .py, в котором я определил некоторые классы. Когда я запускаю файл и использую процедуры, определенные в классах, все работает нормально. Теперь я хочу создать основной .py-файл, который будет импортировать файл со всеми определениями, то есть «from some_file import *». Теперь, когда я запускаю этот файл, одна процедура не работает и дает NameError (глобальное имя some_attribute не определено). Теперь эта процедура определена в одном из классов и использует attibute, созданный внутри другого класса. По какой-то причине эта ссылка не работает, и мне интересно, что я делаю неправильно. Здесь я дам код из «основного» файла:

from fem_obj import * 
nd = Node() 
nd.nodegen(1, 1, 0, 0, 4, 0, 4) 
el = Element() 
el.elgen(1, 1, 1, 2, 1, 1, 3) 

fem_obj является файлом с моими классами Node и Element. nd и el - это, конечно, их экземпляры. nodegen и elgen - это методы. Теперь метод elgen внутри другого файла относится к атрибуту, который создается после вызова процедуры nodegen. И там я получаю ошибку имени. I.e., метод elgen использует nd.nodes, который представляет собой список, который создается методом nodegen.

Я надеюсь, что это достаточно ясно, я могу отправить код другого файла, если это необходимо. Заранее благодарю за любую помощь.

ОК, вот код для fem_obj:

from math import hypot, sqrt 
from Tkinter import * 

class Node: 

    def __init__(self): 
     self.nodes = [] 
     self.nodenum = 0 

    def nodegen(self, slabel, dlabel, sx, sy, dx, dy, num):  
     for i in range(1, num + 1):     
      label = slabel + (i - 1)*dlabel 
      if self.nodecheck(label) == True: 
       return "Node %s already exists!" %label    
      self.nodes = self.nodes + [[label, (sx + (i - 1)*dx, sy + (i - 1)*dy), (0, 0, 0)]] 
      self.nodenum += 1 

    def nodegenf(self, slabel, dlabel, sx, dx, num): 
     f = lambda x: sqrt(1 - x**2) 
     for i in range(1, num + 1):     
      label = slabel + (i - 1)*dlabel 
      if self.nodecheck(label) == True: 
       return "Node %s already exists!" %label    
      self.nodes = self.nodes + [[label, (sx + (i - 1)*dx, f(sx + (i - 1)*dx)), (0, 0, 0)]] 
      self.nodenum += 1  

    def nodeadd(self, label, sx, sy): 
     if self.nodecheck(label) == True: 
      return "Node %s already exists!" %label 
     self.nodes = self.nodes + [[label, (sx, sy), (0, 0, 0)]] 
     self.nodenum += 1   

    def nodedel(self, label): 
     if self.nodecheck(label) == False: 
      return "Node %s does not exist!" %label 
     for i in el.elements: 
      if label in i[1]: 
       return "Node %s attached to element %s!" %(label, i[0]) 
     for i in self.nodes: 
      if label == i[0]: 
       self.nodes.remove(i) 
     self.nodenum -= 1     

    def nodecheck(self, label): 
     for i in self.nodes: 
      if label == i[0]: 
       return True 
     return False 

    def noderes(self, label, u, v, r): 
     if self.nodecheck(label) == False: 
      return "Node %s does not exist!" %label 
     for i in self.nodes: 
      if label == i[0]: 
       i[2] = (u, v, r)  

    def nodelist(self): 
     if self.nodes == []: 
      return "No nodes defined!" 
     print "\n" 
     print "NUMBER OF NODES: ", self.nodenum 
     print "\n" 
     print "NODE COORDINATES RESTRAINTS" 
     print "---- ----------- ----------" 
     print "\n" 
     for i in self.nodes: 
      print i[0], " ", i[1], "  ", i[2] 


class Element: 

    def __init__(self): 
     self.elements = [] 
     self.elnum = 0 

    def elgen(self, slabel, dlabel, snl, enl, sndl, endl, num): 
     for i in range(1, num + 1):     
      label = slabel + (i - 1)*dlabel 
      if self.elcheck(label) == True: 
       return "Element %s already exists!" %label 
      if self.elements != []: 
       for j in self.elements: 
        if j[1] == (snl + (i - 1)*sndl, enl + (i - 1)*endl): 
         return "Element %s endnodes already taken!" %label 
      hlplst = [] 
      for j in nd.nodes: # nd reference 
       hlplst = hlplst + [j[0]] 
      if snl + (i - 1)*sndl not in hlplst: 
       return "Node %s does not exist" %(snl + (i - 1)*sndl) 
      if enl + (i - 1)*endl not in hlplst: 
       return "Node %s does not exist" %(enl + (i - 1)*endl)        
      self.elements = self.elements + [[label, (snl + (i - 1)*sndl, enl + (i - 1)*endl)]] 
      self.elnum +=1 
     self.ellen() 

    def elcheck(self, label): 
     for i in self.elements: 
      if label == i[0]: 
       return True 
     return False 

    def eladd(self, label, snl, enl): 
     if self.elcheck(label) == True: 
      return "Element %s already exists!" %label 
     if self.elements != []: 
      for j in self.elements: 
       if j[1] == (snl, enl):   
        return "Endnodes already taken by element %s!" %j[0] 
     hlplst = [] 
     for j in nd.nodes: # nd reference 
      hlplst = hlplst + [j[0]] 
     if snl not in hlplst: 
      return "Node %s does not exist" %snl 
     if enl not in hlplst: 
      return "Node %s does not exist" %enl 
     self.elements = self.elements + [[label, (snl, enl)]] 
     self.elnum +=1 
     self.ellen() 

    def eldel(self, label): 
     if self.elcheck(label) == False: 
      return "Element %s does not exist!" %label 
     for i in self.elements: 
      if label == i[0]: 
       self.elements.remove(i) 
     self.elnum -=1 

    def ellen(self): 
     if self.elements == []: 
      return "No elements defined!" 
     for i in self.elements: 
      if len(i) == 2: 
       x1 = y1 = x2 = y2 = 0 
       for j in nd.nodes: 
        if i[1][0] == j[0]: 
         x1 = j[1][0] 
         y1 = j[1][1] 
        elif i[1][1] == j[0]: 
         x2 = j[1][0] 
         y2 = j[1][1] 
       i.append(round(hypot(x1 - x2, y1 - y2), 4)) 
      else: 
       continue    

    def ellist(self): 
     if self.elements == []: 
      return "No elements defined!" 
     print "\n" 
     print "NUMBER OF ELEMENTS: ", self.elnum 
     print "\n" 
     print "ELEMENT START NODE END NODE LENGTH SECTION" 
     print "------- ---------- -------- ------ -------" 
     print "\n" 
     for i in self.elements: 
      if len(i) < 4: 
       print i[0], "   ", i[1][0], "   ", i[1][1], "  ", i[2], "  ", "NONE" 
      else: 
       print i[0], "   ", i[1][0], "   ", i[1][1], "  ", i[2], "  ", i[3]     

    def sctassign(self, label, slabel, elabel, dlabel): 
     for i in s1.sections: # s1 reference 
      if label == i[0]: 
       break 
      return "Section %s does not exist!" %label 

     j = 0 
     while slabel + j*dlabel <= elabel: 
      for i in self.elements: 
       if i[0] == slabel + j*dlabel: 
        i.append(label) 
        j += 1 
        continue 
       else: 
        return "Element %e does not exist!" %(slabel + j*dlabel) 

Я поставил #nd ссылку внутри класса Element, где, кажется, проблема. Извините, код немного длинный ... (строка, в которой появляется ссылочный комментарий #nd, - это строка NameError)

+0

Я не получаю связь между elgen и nd.nodes. Как бы el.elgen знал и даже существовал, чтобы получить доступ к nd.nodes? Есть ли какое-то скрытое глобальное состояние? – DSM

+0

Код другого файла - это то, что актуально, потому что это звучит так, как будто генерируется NameError (хотя это немного неясно). Btw, 'from foo import *' - ужасная идея. – geoffspear

+0

Пожалуйста, разместите код другого файла. Необходимо избегать догадок :) –

ответ

3

Возможно, я неправильно понял, потому что это кажется прямым.Ошибка имя:

Traceback (most recent call last): 
    File "main.py", line 5, in <module> 
    el.elgen(1, 1, 1, 2, 1, 1, 3) 
    File "/home/snim2/Dropbox/scratch/so/fem_obj.py", line 86, in elgen 
    for j in nd.nodes: # nd reference 
NameError: global name 'nd' is not defined 

и линии 86 появляется в этом контексте:

def elgen(self, slabel, dlabel, snl, enl, sndl, endl, num): 
    for i in range(1, num + 1):     
     label = slabel + (i - 1)*dlabel 
     if self.elcheck(label) == True: 
      return "Element %s already exists!" %label 
     if self.elements != []: 
      for j in self.elements: 
       if j[1] == (snl + (i - 1)*sndl, enl + (i - 1)*endl): 
        return "Element %s endnodes already taken!" %label 
     hlplst = [] 
     for j in nd.nodes: # nd reference 
      hlplst = hlplst + [j[0]] 
     if snl + (i - 1)*sndl not in hlplst: 
      return "Node %s does not exist" %(snl + (i - 1)*sndl) 
     if enl + (i - 1)*endl not in hlplst: 
      return "Node %s does not exist" %(enl + (i - 1)*endl)        
     self.elements = self.elements + [[label, (snl + (i - 1)*sndl, enl + (i - 1)*endl)]] 
     self.elnum +=1 
    self.ellen() 

Так что, если вы хотите elgen, чтобы иметь возможность использовать массив из Node с, вам нужно передать их в этот метод в качестве аргумента, например:

def elgen(self, nd, slabel, dlabel, snl, enl, sndl, endl, num): 
    for i in range(1, num + 1):     
     label = slabel + (i - 1)*dlabel 
     if self.elcheck(label) == True: 
      return "Element %s already exists!" %label 
     if self.elements != []: 
      for j in self.elements: 
       if j[1] == (snl + (i - 1)*sndl, enl + (i - 1)*endl): 
        return "Element %s endnodes already taken!" %label 
     hlplst = [] 
     for j in nd.nodes: # nd reference 
      hlplst = hlplst + [j[0]] 
     if snl + (i - 1)*sndl not in hlplst: 
      return "Node %s does not exist" %(snl + (i - 1)*sndl) 
     if enl + (i - 1)*endl not in hlplst: 
      return "Node %s does not exist" %(enl + (i - 1)*endl)        
     self.elements = self.elements + [[label, (snl + (i - 1)*sndl, enl + (i - 1)*endl)]] 
     self.elnum +=1 
    self.ellen() 

и в main.py:

nd = Node() 
nd.nodegen(1, 1, 0, 0, 4, 0, 4) 
el = Element() 
el.elgen(nd, 1, 1, 1, 2, 1, 1, 3) 
+0

Я отредактировал код и добавил «nd» в качестве аргумента для процедур, которые его используют. Теперь это работает. Спасибо за помощь. –

0

Я не зашел так далеко, чтобы выяснить все, что должен делать код, однако у вас есть проблемная линия ...

for j in nd.nodes: # nd reference 

который относится к переменной «nd». Я не вижу, где определено «nd», кроме main.py. main.py не будет найден. Вы можете упростить эту проблему в следующем странствующих код:

main.py:

from feb_obj import run 
nd = "Test" 
run() 

feb_obj.py:

def run(): 
    print nd # This won't work! 

Я считаю, что вы ожидаете, что знать, что "е место" - это переменная, определенная в файле «main.py». Это не то, как работает python. «fem_obj.py» будет видеть только то, что определено в его собственной области. Он знает, что «hypot» и «sqrt» - это потому, что вы их импортировали. Однако он не знает о переменных в других модулях, включая файл main.py.

+0

Ну, nd определяется внутри класса Nodes, а в основном модуле выполняется перед частью, где я имею в виду. Это все еще немного сбивает меня с толку - я не уверен, что это пространство имен для этой переменной - очевидно, в модуле fem_obj, так как основной модуль не видит этого. –

Смежные вопросы