简体   繁体   中英

Python module importing issue

I won't post the code, I'll only quote relevant parts, since it's a bit long.

So, I have a main .py file where I defined some classes. When I run the file and use the procedures defined in the classes, everything works fine. Now, I want to create a main .py file which will import the file with all the definitions, ie "from some_file import *". Now, when I execute this file, one procedure doesn't work and gives the NameError (global name some_attribute is not defined). Now, this procedure is defined in one of the classes, and uses an attibute created inside another of the classes. For some reason, this reference doesn't work and I wonder what I'm doing wrong. Here, I'll give the code from the "main" file:

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 is the file with my classes Node and Element. nd and el are of course their instances. nodegen and elgen are methods. Now, the elgen method inside the other file refers to an attribute which is created after the nodegen procedure is called. And there i get a name error. Ie, the elgen method uses nd.nodes, which is a list which is created by the nodegen method.

I hope this is clear enough, I can post the code of the other file if necessary. Thanks in advance for any help.

OK, here's the code for 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)

I put #nd reference inside the Element class where there seems to be a problem. Sorry, the code's a bit long...(the line where the #nd reference comment appears is the NameError line)

Maybe I've misunderstood, because this seems straight forward. The name error is:

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

and line 86 appears in this context:

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()

So, if you want elgen to be able to use your array of Node s, you need to pass them into that method as an argument, like this:

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()

and in 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)

I didn't go so far as to figure out everything that the code is supposed to be doing, however, you have the troubled line...

for j in nd.nodes: # nd reference

which refers to a variable "nd". I don't see where "nd" is defined, except in main.py . main.py is not going to be found. You can simplify this problem into the following errant code:

main.py:

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

feb_obj.py:

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

I believe you're expecting it to know that "nd" is the variable defined in the "main.py" file. This is not how python works. "fem_obj.py" will only see what is defined within it's own scope. It knows what "hypot" and "sqrt" are because you imported them. However, it does not know about variables in other modules, including the main.py file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM