Python - NameError: name“未定义”。

时间:2022-07-14 18:14:13

I am currently expanding by python skills by programming a procedurally generated dungeon level in text format. I am confused as to why my "intersects" define is not working. Here is the class containing the def:

目前,我正在通过编程以文本格式编写程序生成的地牢级别来扩展python技能。我很困惑,为什么我的“交叉”定义不起作用。这里是包含def的类:

class Room:

    global x1
    global x2
    global y1
    global y2

    global w
    global h

    global centre

    def __init__(self,x,y,w,h):
        x1 = x
        x2 = x + w
        y1 = y
        y2 = y + h
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        centre = math.floor((x1 + x2) / 2),math.floor((y1 + y2) / 2)

    #function that checks if the rooms intersect by comparing corner pins relative to the x,y tile map 
    def intersects(self,room):
        if x1 <= room.x2 and x2 >= room.x1 and y1 <= room.y2 and room.y2 >=  room.y1:
            return True
        return False

Here is where it's called:

这里是它的名字:

def placeRooms(r):
    rooms = []
    #Where the room data is stored

    for r in range(0,r):
        w = minRoomSize + randint(minRoomSize,maxRoomSize)
        h = minRoomSize + randint(minRoomSize,maxRoomSize)
        x = randint(1,map_width - w - 1) + 1
        y = randint(1,map_height - h - 1) + 1

        newRoom = Room(x,y,w,h)

        failed = False

        #for every room generated, this function checks if new room intersects with the last one
        for otherRoom in rooms:
            if newRoom.intersects(otherRoom):
                failed = True
                break

        if failed == False:
            createRoom(newRoom)

            rooms.append(newRoom)

Full traceback:

完整回溯:

Traceback (most recent call last):
File "C:\Users\Max\Desktop\LiClipse Workspace\testing\RandomDungeon.py",      line 78, in <module>
placeRooms(2)
File "C:\Users\Max\Desktop\LiClipse Workspace\testing\RandomDungeon.py",  line  65, in placeRooms
if newRoom.intersects(otherRoom):
File "C:\Users\Max\Desktop\LiClipse Workspace\testing\RandomDungeon.py",   line 41, in intersects
if x1 <= room.x2 and x2 >= room.x1 and y1 <= room.y2 and room.y2 >= room.y1:
NameError: name 'x1' is not defined

I hope someone can help me understand why this code won't work, thank you.

我希望有人能帮助我理解为什么这段代码不起作用,谢谢。

I have managed to fix the problem. I'm sorry if my question was not defined very well. I have only been learning Python for around 4 weeks and i am used to Java which has a very different syntax. Here is my solution:

我已经设法解决了这个问题。如果我的问题没有得到很好的定义,我很抱歉。我只学习了大约4周的Python,我习惯了Java,它的语法非常不同。这是我的解决方案:

def __init__(self,x,y,w,h):
    self.x1 = x
    self.x2 = x + w
    self.y1 = y
    self.y2 = y + h
    self.x = x
    self.y = y
    self.w = w
    self.h = h

1 个解决方案

#1


1  

As most previous comments have said, you use global variables that shouldn't be global at all.

正如大多数先前的评论所说,您使用的全局变量不应该是全局变量。

The way I understand your code, you meant for x1, x2, y1 and y2 to be attributes of your Room instance, meaning that each room has its own values for x1, x2, y1 and y2. In Python you don't have to declare attributes at the beginning of the class (where you declare all the global variables), you simply need to initialize the attributes in the __init__ method.

我理解你的代码的方式,你的意思是,你的房间实例的属性是x1, x2, y1和y2,这意味着每个房间都有自己的x1, x2, y1和y2的值。在Python中,您不必在类的开头声明属性(在这里声明所有全局变量),您只需在__init__方法中初始化属性。

This means that you can safely delete all the global lines, and change your __init__ to

这意味着您可以安全地删除所有的全局行,并更改您的__init__。

def __init__(self,x,y,w,h):
    self.x1 = x
    self.x2 = x + w
    self.y1 = y
    self.y2 = y + h
    self.w = w
    self.h = h
    centre = (self.x1 + self.x2) // 2,(self.y1 + self.y2) // 2

(note that you don't need math.floor since you're already dealing with integers, simply use the integer division operator //)

(注意你不需要数学。因为你已经在处理整数了,只需使用整数除法运算符//)

That way you define x1, y1, x2, y2, w, h and center as attributes of your class meaning that each instance has its own values for these variables. In Python, you need to add self. before all calls to attributes of the object itself, so you should also modify intersects to add self. before each access to an attribute of your current object (all the x1, x2, etc. that are not already prefixed by room. in your code).

这样你定义了x1, y1, x2, y2, w, h和center作为你的类的属性,这意味着每个实例都有它自己的值。在Python中,您需要添加self。在调用对象本身的属性之前,您还应该修改交叉以添加self。在每次访问当前对象的属性之前(所有的x1、x2等都不是已经被房间预先设置的)。在您的代码)。

Also, while we're at it I don't think your intersect function works as intended, but that's another problem :)

而且,虽然我们在这里,我不认为你的交叉功能是有意的,但那是另一个问题:)

#1


1  

As most previous comments have said, you use global variables that shouldn't be global at all.

正如大多数先前的评论所说,您使用的全局变量不应该是全局变量。

The way I understand your code, you meant for x1, x2, y1 and y2 to be attributes of your Room instance, meaning that each room has its own values for x1, x2, y1 and y2. In Python you don't have to declare attributes at the beginning of the class (where you declare all the global variables), you simply need to initialize the attributes in the __init__ method.

我理解你的代码的方式,你的意思是,你的房间实例的属性是x1, x2, y1和y2,这意味着每个房间都有自己的x1, x2, y1和y2的值。在Python中,您不必在类的开头声明属性(在这里声明所有全局变量),您只需在__init__方法中初始化属性。

This means that you can safely delete all the global lines, and change your __init__ to

这意味着您可以安全地删除所有的全局行,并更改您的__init__。

def __init__(self,x,y,w,h):
    self.x1 = x
    self.x2 = x + w
    self.y1 = y
    self.y2 = y + h
    self.w = w
    self.h = h
    centre = (self.x1 + self.x2) // 2,(self.y1 + self.y2) // 2

(note that you don't need math.floor since you're already dealing with integers, simply use the integer division operator //)

(注意你不需要数学。因为你已经在处理整数了,只需使用整数除法运算符//)

That way you define x1, y1, x2, y2, w, h and center as attributes of your class meaning that each instance has its own values for these variables. In Python, you need to add self. before all calls to attributes of the object itself, so you should also modify intersects to add self. before each access to an attribute of your current object (all the x1, x2, etc. that are not already prefixed by room. in your code).

这样你定义了x1, y1, x2, y2, w, h和center作为你的类的属性,这意味着每个实例都有它自己的值。在Python中,您需要添加self。在调用对象本身的属性之前,您还应该修改交叉以添加self。在每次访问当前对象的属性之前(所有的x1、x2等都不是已经被房间预先设置的)。在您的代码)。

Also, while we're at it I don't think your intersect function works as intended, but that's another problem :)

而且,虽然我们在这里,我不认为你的交叉功能是有意的,但那是另一个问题:)