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.