【问题标题】:Python 3.2 vs Python 2.7 code problemsPython 3.2 与 Python 2.7 代码问题
【发布时间】:2026-02-09 06:40:01
【问题描述】:

我有一个使用 pygame 绘制 mandlebrot 集的代码。这是代码。

import pygame, sys, math
from decimal import *
window=pygame.display.set_mode((1000, 1000))
window.fill((255, 255, 255))
pygame.display.update()
winrect=window.get_rect()
hq=3
getcontext().prec=20
colors=((255, 0, 0), (255, 128, 0), (255, 255, 0), (128, 255, 0), (0, 255, 0), (0, 255, 128), (0, 255, 255), (0, 128, 255), (0, 0, 255), (128, 0, 255), (255, 0, 255), (255, 0, 128))
def graph(scale):#left, right, bottom, top
    window.fill((0, 0, 0))
    minimum=-1
    y=((scale[3]-scale[2]))/(winrect.height)+scale[2]
    for a in range(winrect.width):
        x=((scale[1]-scale[0])*(a))/(winrect.width)+scale[0]
        d, e=x**2-y**2+x, 2*x*y+y
        for i in range(int(1/(50*(scale[1]-scale[0]))+25)):
            d, e=d**2-e**2+x, 2*d*e+y
            if math.sqrt(d**2+e**2)>2:
                if i<minimum or minimum==-1:
                    minimum=i
                break
    y=((scale[3]-scale[2])*winrect.height)/(winrect.height)+scale[2]
    for a in range(winrect.width):
        x=((scale[1]-scale[0])*a)/winrect.width+scale[0]
        d, e=x**2-y**2+x, 2*x*y+y
        for i in range(int(1/(50*(scale[1]-scale[0]))+25)):
            d, e=d**2-e**2+x, 2*d*e+y
            if math.sqrt(d**2+e**2)>2:
                if i<minimum or minimum==-1:
                    minimum=i
                break
    x=((scale[1]-scale[0])*1)/winrect.width+scale[0]
    for b in range(winrect.height):
        y=((scale[3]-scale[2])*b)/winrect.height+scale[2]
        d, e=x**2-y**2+x, 2*x*y+y
        for i in range(int(1/(50*(scale[1]-scale[0]))+25)):
            d, e=d**2-e**2+x, 2*d*e+y
            if math.sqrt(d**2+e**2)>2:
                if i<minimum or minimum==-1:
                    minimum=i
                break
    x=((scale[1]-scale[0])*winrect.width)/winrect.width+scale[0]
    for b in range(winrect.height):
        y=((scale[3]-scale[2])*b)/winrect.height+scale[2]
        d, e=x**2-y**2+x, 2*x*y+y
        for i in range(int(1/(50*(scale[1]-scale[0]))+25)):
            d, e=d**2-e**2+x, 2*d*e+y
            if math.sqrt(d**2+e**2)>2:
                if i<minimum or minimum==-1:
                    minimum=i
                break
    for a in range(winrect.width):
        for b in range(winrect.height):
            x=((scale[1]-scale[0])*a)/winrect.width+scale[0]
            y=((scale[3]-scale[2])*b)/winrect.height+scale[2]
            d, e=x**2-y**2+x, 2*x*y+y
            for i in range(minimum):
                d, e=d**2-e**2+x, 2*d*e+y
            for i in range(20*hq):
                d, e=d**2-e**2+x, 2*d*e+y
                if math.sqrt(d**2+e**2)>2:
                    window.set_at((a, b), colors[i-(int(i/len(colors))*len(colors))])
                    break
            for event in pygame.event.get():
                if event.type==pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type==pygame.KEYDOWN:
                    if event.key==pygame.K_ESCAPE:
                        pygame.quit()
                        sys.exit()
        pygame.display.update()
    pygame.display.update()
graph([-3, 2, -2.5, 2.5, 0])#
scale=[-3, 2, -2.5, 2.5, 0]
scalea=scale[:]
while True:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type==pygame.KEYDOWN:
            if event.key==pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()
            if event.key==pygame.K_r:
                graph([-3, 2, -2.5, 2.5, 0])
                scale=[-3, 2, -2.5, 2.5, 0]
                scalea=scale[:]
            if event.key==pygame.K_p:
                hq+=1
                graph(scale)
            if event.key==pygame.K_o:
                if not hq==1:
                    hq-=1
                    graph(scale)
            if event.key==pygame.K_SPACE:
                print(scale)
                print(scale[1]-scale[0])
        if event.type==pygame.MOUSEBUTTONDOWN:
            if not scalea[4]:
                scalea[0]=(((scale[1]-scale[0])*event.pos[0])/winrect.width)+scale[0]
                scalea[2]=(((scale[3]-scale[2])*event.pos[1])/winrect.height)+scale[2]
                scalea[4]=1
            else:
                scalea[1]=(((scale[1]-scale[0])*event.pos[0])/winrect.width)+scale[0]
                scalea[3]=(((scale[3]-scale[2])*event.pos[1])/winrect.height)+scale[2]
                scalea[4]=0
                if scalea[1]<scalea[0]:
                    scalea=[scalea[1], scalea[0], scalea[2], scalea[3], 0]
                if scalea[3]<scalea[2]:
                    scalea=[scalea[0], scalea[1], scalea[3], scalea[2], 0]
                scale=scalea[:]
                if scale[1]-scale[0]<scale[3]-scale[2]:
                    scale[1]+=((scalea[3]-scalea[2])-(scalea[1]-scalea[0]))/2
                    scale[0]-=((scalea[3]-scalea[2])-(scalea[1]-scalea[0]))/2
                else:
                    scale[2]-=((scalea[1]-scalea[0])-(scalea[3]-scalea[2]))/2
                    scale[3]+=((scalea[1]-scalea[0])-(scalea[3]-scalea[2]))/2
                graph(scale)

当我在 python 3.2 中运行它时,它运行良好。图像如下所示:

但是,当我在 python 2.7 中运行它时,我得到一个看起来很可怕的图像,看起来像这样:

有什么办法可以解决这个问题吗?

【问题讨论】:

  • 你只说“可怕”,因为它不是你所期望的。我觉得它看起来很棒!
  • 看起来像“BIT.TRIP Mandelbrot”... ^^
  • @Todd 你一定喜欢现代艺术。

标签: python python-2.7 python-3.x pygame


【解决方案1】:

是的,将其添加到文件顶部:

from __future__ import division

Python 2 在默认使用整数输入时使用整数除法(下除法);即使使用整数输入,Python 3 也切换到浮点除法。

查看PEP 238,其中记录了更改:

当前除法 (/) 运算符的含义不明确 数值参数:它返回数学的下限 如果参数是整数或长整数,则除法的结果,但它 返回除法结果的合理近似值,如果 参数是浮点数或复数。这使得表达式期待 当整数不是时,浮点或复杂结果容易出错 预期但可能作为输入。

【讨论】:

  • 这很好用,但我还有另一个问题。即使我在 3.2 上,一旦我放大很多,我得到的图片与以前的 2.7 相似,我认为这是由于 Python 缺乏精度。我使用十进制模块试图摆脱它,但这样做需要更长的时间。有什么解决办法吗?
  • 不是真的;浮点确实有精度限制,但是因为它们是由您的 PC 硬件处理的,所以它们的处理速度也快得多。您可以改用integers to calculate the mandelbrot。这就是我在 20 多年前使用分形的方式,无论如何,使用 FRACTINT。 :-)
【解决方案2】:

在顶部添加from __future__ import division

【讨论】: