错误与行号有关,与代码无关。如何解决?
Error connected with line number and not the code. How to fix it?
我正在编写一个自学习汽车的程序,该程序可以行驶到 pygame
和 cython
的点。我认为问题是由 cython
编译器而不是 pygame
引起的,因为在该方法中与 pygame
没有任何联系。但是,当我对 .pyd 文件进行 cython 化时,没有给出任何错误。另外,如果我更改任何行的代码,例如,在错误所在的第 99 行之前添加一行,错误行不会移动一个,它会留在第 99 行。因此,错误以某种方式与行号而不是代码有关。这怎么可能?
这是 class 和我遇到错误的方法:
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", 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'
编辑:如您所见,错误在第 99 行,但第 99 行是
self.car_angle = car_angle # from -pi to pi
与属性形状无关。
我已经在 init 函数之前得到了 class 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, sine, cosine), self.shift_y(self.p1.x, self.p1.y, sine, cosine)
self.p2.x, self.p2.y = self.shift_x(self.p2.x, self.p2.y, sine, cosine), self.shift_y(self.p2.x, self.p2.y, sine, cosine)
self.p3.x, self.p3.y = self.shift_x(self.p3.x, self.p3.y, sine, cosine), self.shift_y(self.p3.x, self.p3.y, sine, cosine)
self.p4.x, self.p4.y = self.shift_x(self.p4.x, self.p4.y, sine, cosine), self.shift_y(self.p4.x, self.p4.y, sine, cosine)
cdef shift_x(self, double x, double y, sine, cosine):
return cosine * (x - self.center.x) + sine * (y - self.center.y) + self.center.x
cdef shift_y(self, double x, double y, sine, 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, 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
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, 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 创建文件。而且我也不知道该怎么做。
因此,有 2 种可能的解决方案:
- 将所有库移动到 python 3.9
- 说 cython 编译器使用 3.8 版本
问题出在 cython 和 python 版本上。现在我在 python 3.9 上做这个项目。我下载了这个项目需要的所有库,但如果有人能帮助我将所有 python 3.8 库移动到 3.9 而无需手动下载它们,那就更好了。
我正在编写一个自学习汽车的程序,该程序可以行驶到 pygame
和 cython
的点。我认为问题是由 cython
编译器而不是 pygame
引起的,因为在该方法中与 pygame
没有任何联系。但是,当我对 .pyd 文件进行 cython 化时,没有给出任何错误。另外,如果我更改任何行的代码,例如,在错误所在的第 99 行之前添加一行,错误行不会移动一个,它会留在第 99 行。因此,错误以某种方式与行号而不是代码有关。这怎么可能?
这是 class 和我遇到错误的方法:
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", 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'
编辑:如您所见,错误在第 99 行,但第 99 行是
self.car_angle = car_angle # from -pi to pi
与属性形状无关。
我已经在 init 函数之前得到了 class 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, sine, cosine), self.shift_y(self.p1.x, self.p1.y, sine, cosine)
self.p2.x, self.p2.y = self.shift_x(self.p2.x, self.p2.y, sine, cosine), self.shift_y(self.p2.x, self.p2.y, sine, cosine)
self.p3.x, self.p3.y = self.shift_x(self.p3.x, self.p3.y, sine, cosine), self.shift_y(self.p3.x, self.p3.y, sine, cosine)
self.p4.x, self.p4.y = self.shift_x(self.p4.x, self.p4.y, sine, cosine), self.shift_y(self.p4.x, self.p4.y, sine, cosine)
cdef shift_x(self, double x, double y, sine, cosine):
return cosine * (x - self.center.x) + sine * (y - self.center.y) + self.center.x
cdef shift_y(self, double x, double y, sine, 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, 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
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, 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 创建文件。而且我也不知道该怎么做。
因此,有 2 种可能的解决方案:
- 将所有库移动到 python 3.9
- 说 cython 编译器使用 3.8 版本
问题出在 cython 和 python 版本上。现在我在 python 3.9 上做这个项目。我下载了这个项目需要的所有库,但如果有人能帮助我将所有 python 3.8 库移动到 3.9 而无需手动下载它们,那就更好了。