如何解决错误与行号而非代码相关如何解决?
我正在编写一个自动学习汽车的程序,它使用 pygame
和 cython
行驶到某个点。我认为问题在某种程度上是由 cython
编译器而不是 pygame
引起的,因为在该方法中与 pygame
没有任何关系。但是,当我对 .pyd 文件进行 cythonize 时,没有给出错误。另外如果我把代码改成任意一行,比如在错误所在的第99行之前加一行,错误行不会移动一个,而是停留在第99行。因此,错误以某种方式与行号而不是代码有关。这怎么可能?
这是我遇到错误的类和方法:
cdef class Car:
cdef:
double speed,car_angle,wheel_angle
Point position
polygon shape
def __init__(self,position=(0.0,0.0),speed=0.5,car_angle=0.0,wheel_angle=0.0):
self.position = Point(*position)
self.shape = polygon(self.position,CAR_SHAPE[0],CAR_SHAPE[1],self.car_angle)
self.speed = speed
self.car_angle = car_angle # from -pi to pi
self.wheel_angle = wheel_angle # from -MAX_WHEEL_ANGLE to MAX_WHEEL_ANGLE
错误:
Traceback (most recent call last):
File "main.pyx",line 83,in main.Population.__init__
self.cars = [Car(position=CAR_START_POS,car_angle=random.random() * 2 - 1) for _ in range(amount)]
File "main.pyx",line 99,in main.Car.__init__
self.car_angle = car_angle # from -pi to pi
AttributeError: 'main.Car' object has no attribute 'shape'
Exception ignored in: 'main.main'
Traceback (most recent call last):
File "main.pyx",in main.Car.__init__
self.car_angle = car_angle # from -pi to pi
AttributeError: 'main.Car' object has no attribute 'shape'
编辑:如您所见,错误在第 99 行,但第 99 行是
self.car_angle = car_angle # from -pi to pi
它与属性形状无关。
我已经在 init 函数之前获得了 Car
类的所有定义。而且属性形态也在里面。那为什么说没有这个属性呢?
我使用的是 python 3.8,cython 0.29.21 如果需要,这里是整个代码:
import random
from math import sin,cos,pi,sqrt
import numpy as np
import pygame
pygame.init()
cdef:
tuple BG_COLOR = (10,10,20)
tuple SIZE = (800,600)
double MAX_WHEEL_ANGLE = 0.872665
tuple CAR_COLOR = (200,200,200)
tuple CAR_SHAPE = (23,10)
tuple CAR_START_POS = (SIZE[0] / 2,SIZE[1])
clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial",18)
screen = pygame.display.set_mode(SIZE,pygame.NOFRAME)
def update_fps():
cdef:
str fps = str(int(clock.get_fps()))
fps_text = font.render(fps,True,pygame.Color("coral"))
return fps_text
cdef class Point():
cdef double x,y
cdef shift_x,shift_y
def __init__(self,double x,double y):
self.x = x
self.y = y
def __str__(self):
return self.x,self.y
cdef tuple to_array(self):
return (self.x,self.y)
cdef void rotate(self,Point center,double sine,double cosine):
self.x = cosine * (self.x - center.x) + sine * (self.y - center.y) + center.x
self.y = -sine * (self.x - center.x) + cosine * (self.y - center.y) + center.y
cdef class polygon():
cdef:
Point center,p1,p2,p3,p4
double length,width,radius,angle,sine,cosine
def __init__(self,center: Point,length: double,width: double,angle: double):
self.center = center
self.length = length
self.width = width
self.radius = sqrt(width ** 2 + length ** 2)
self.p1 = Point(center.x - width / 2,center.y + length / 2)
self.p2 = Point(center.x + width / 2,center.y + length / 2)
self.p3 = Point(center.x + width / 2,center.y - length / 2)
self.p4 = Point(center.x - width / 2,center.y - length / 2)
self.angle = angle
sine,cosine = sin(pi - self.angle),cos(pi - self.angle)
self.p1.x,self.p1.y = self.shift_x(self.p1.x,self.p1.y,cosine),self.shift_y(self.p1.x,cosine)
self.p2.x,self.p2.y = self.shift_x(self.p2.x,self.p2.y,self.shift_y(self.p2.x,cosine)
self.p3.x,self.p3.y = self.shift_x(self.p3.x,self.p3.y,self.shift_y(self.p3.x,cosine)
self.p4.x,self.p4.y = self.shift_x(self.p4.x,self.p4.y,self.shift_y(self.p4.x,cosine)
cdef shift_x(self,double y,cosine):
return cosine * (x - self.center.x) + sine * (y - self.center.y) + self.center.x
cdef shift_y(self,cosine):
return -sine * (x - self.center.x) + cosine * (y - self.center.y) + self.center.y
def __str__(self):
return (self.p1,self.p2,self.p3,self.p4)
cdef tuple to_array(self):
return self.p1.to_array(),self.p2.to_array(),self.p3.to_array(),self.p4.to_array()
cdef class Population:
cdef list cars
def __init__(self,amount: int):
self.cars = [Car(position=CAR_START_POS,car_angle=random.random() * 2 - 1) for _ in range(amount)]
cdef void go(self):
for car in self.cars:
car.go()
cdef class Car:
cdef:
double speed,self.car_angle)
self.speed = speed
self.car_angle = car_angle # from -pi to pi
self.wheel_angle = wheel_angle # from -MAX_WHEEL_ANGLE to MAX_WHEEL_ANGLE
cdef void go(self):
self.position.y -= np.cos(self.car_angle) * self.speed
self.position.x += np.sin(self.car_angle) * self.speed
self.car_angle += self.wheel_angle
self.draw()
cdef void draw(self):
pygame.draw.polygon(screen,CAR_COLOR,self.shape.to_array(),3)
pygame.draw.circle(screen,(255,0),(self.position.x,self.position.y),1)
cdef class DNA:
pass
cpdef void main():
cdef bint close_program = False
cdef Population cars = Population(1000)
while not close_program:
screen.fill(BG_COLOR)
cars.go()
screen.blit(update_fps(),(10,0))
clock.tick(60)
pygame.display.flip()
if __name__ == '__main__':
main()
EDIT2: 问题很可能出在 python 和 cython 版本上。它创建的 .pyd
文件是 main.cp39-win_amd64
,所以这意味着 cython 为 python 3.9 创建了一个文件,我使用 3.8,但试图从 3.8 到 3.9。不幸的是,我不能将所有下载的库从 3.8 移动到 3.9,因此,继续使用旧版本。如果您知道如何移动所有库,请帮助我。否则,我必须以某种方式说 cython 为 python 3.8 创建文件。我也不知道该怎么做。
因此,有两种可能的解决方案:
- 将所有库移至 python 3.9
- 说 cython 编译器可以使用 3.8 版本
解决方法
问题出在 cython 和 python 版本上。现在我在 python 3.9 上做这个项目。我下载了这个项目所需的所有库,但如果有人能帮助我将所有 python 3.8 库移动到 3.9 而无需手动下载它们会更好。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。