Python 函数无意识地改变变量

Python 函数无意识地改变变量,python,variables,scale,python-imaging-library,Python,Variables,Scale,Python Imaging Library,我想在rotateshape()中的for循环中使用baseTriangle和baseSquare变量,但当它们被放入时,函数似乎会改变它们,这意味着它们随着每个循环而变大。不知道为什么会这样,请帮忙 #! /usr/bin/env python import Image, ImageDraw import math # functions def rotateShape(shapeXCoordinates, shapeYCoordinates, b

我想在rotateshape()中的for循环中使用baseTriangle和baseSquare变量,但当它们被放入时,函数似乎会改变它们,这意味着它们随着每个循环而变大。不知道为什么会这样,请帮忙

    #! /usr/bin/env python

    import Image, ImageDraw
    import math

    # functions

    def rotateShape(shapeXCoordinates, shapeYCoordinates, baseXCoordinates, baseYCoordinates):

        # Written by: some guy who had to do this once and thought it better to share rather than let other people suffer through the monotony

        # This function below takes a shape and rotates, scales and translates it so that the first two coordinates are equal to the baseCoordinates

        # Make sure that the distance between the first two shape coordinates is 1 and that they lie on the x-axis



        # Find the dx, dy and the length of the baseCoordinates pair
        #print 'Base coordinates: ' + str(zip(baseXCoordinates, baseYCoordinates))
        dx = baseXCoordinates[1] - baseXCoordinates[0]
        #print 'dx: ' + str(dx)
        dy = baseYCoordinates[1] - baseYCoordinates[0]
        #print 'dy: ' + str(dy)
        magnitude = math.sqrt(dx**2+dy**2)
        #print 'magnitude: ' + str(magnitude)

        #print 'Start: ' + str(zip(shapeXCoordinates, shapeYCoordinates))

        # Rotate the matrix
        a = dx/magnitude
        b = -dy/magnitude
        c = dy/magnitude
        d = dx/magnitude

        for i in range(0,len(shapeXCoordinates)):

            # Find the new x value
            newX = a*shapeXCoordinates[i]+b*shapeYCoordinates[i]

            # Find the new y value
            newY = c*shapeXCoordinates[i]+d*shapeYCoordinates[i]

            # Replace the old with the new
            shapeXCoordinates[i] = newX
            shapeYCoordinates[i] = newY

        #print 'After rotate: ' + str(zip(shapeXCoordinates, shapeYCoordinates))

        # Scale the matrix
        for i in range(0,len(shapeXCoordinates)):

            shapeXCoordinates[i] = shapeXCoordinates[i]*magnitude
            shapeYCoordinates[i] = shapeYCoordinates[i]*magnitude

        #print 'After scale: ' + str(zip(shapeXCoordinates, shapeYCoordinates))

        # Translate the matrix
        for i in range(0,len(shapeXCoordinates)):

            shapeXCoordinates[i] = shapeXCoordinates[i]+baseXCoordinates[0]
            shapeYCoordinates[i] = shapeYCoordinates[i]+baseYCoordinates[0]

        #print 'After translate: ' + str(zip(shapeXCoordinates, shapeYCoordinates))
        return (shapeXCoordinates, shapeYCoordinates)

    # create a bitmap

    img = Image.new('RGB', (3840, 2160))
    draw = ImageDraw.Draw(img)

    # setting up the varibales

    # insert angle

    angle = 30
    angle_2 = 90 - angle
    a = math.sin(angle_2) * 1

    # working out the Y of the triangle

    y = math.sin(angle) * a

    # working out the X of Y

    x = math.tan(angle)/y

    baseTriangle_X = [0, 1, x]
    baseTriangle_Y = [0, 0, y]

    baseSquare_X = [0, 1, 1, 0]
    baseSquare_Y = [0, 0, 1, 1]

    startPosition_X = [1800, 2200] # flipped numbers as bitmap counts from the top left so that tree is created downwards
    startPosition_Y = [0, 0]

    # set number of iterations

    numberOfIterations = 10

    # set colour

    redStart = 255
    greenStart = 253
    blueStart = 208

    redEnd = 228
    greenEnd = 82
    blueEnd = 0

    # colour change

    redChange =(redEnd - redStart)/numberOfIterations
    greenChange =(greenEnd - greenStart)/numberOfIterations
    blueChange =(blueEnd - blueStart)/numberOfIterations

    # set up the list of squares to make (fill with the start position)

    squaresToMake_X = []
    squaresToMake_Y = []

    squaresToMake_X.extend(startPosition_X)
    squaresToMake_Y.extend(startPosition_Y)

    # set up the list of triangles

    trianglesToMake_X = []
    trianglesToMake_Y = []

    # creating the tree

    print '//////////////////////////////'
    print '//     //     //     //     //'
    print '//// //// ////// ////// //////'
    print '//// //// //////     //     //'
    print '//// //// ////// ////// //////'
    print '//// //// //////     //     //'
    print '//////////////////////////////'

    # background colour

    draw.rectangle((0,0,3839,2759), fill=(220, 255, 250))

    for i in xrange(0, numberOfIterations):

        redCurrent =  redStart + redChange  * i
        greenCurrent =  greenStart + greenChange  * i
        blueCurrent =  blueStart + blueChange  * i

        # making squares

        for j in xrange(0, len(squaresToMake_X)/2):

            print 'Iteration ' + str(i) + ' of ' + str(numberOfIterations) + '. Square ' + str(j) + ' of ' +  str(len(squaresToMake_X)/2)
            k = j * 2

            newVertices_X, newVertices_Y = rotateShape([0, 1, 1, 0], [0, 0, 1, 1], squaresToMake_X[k:k+2], squaresToMake_Y[k:k+2])

            # merge x and y
            combinedVertices = zip(newVertices_X, newVertices_Y) 

            # draw 
            #print 'Drawing square:'
            #print combinedVertices
            draw.polygon(combinedVertices, fill = (redCurrent, greenCurrent, blueCurrent))

            trianglesToMake_X.extend([newVertices_X[3], newVertices_X[2]])
            trianglesToMake_Y.extend([newVertices_Y[3], newVertices_Y[2]])

            #print 'Triangles to make:'
            #print zip(trianglesToMake_X, trianglesToMake_Y)

        squaresToMake_X = []
        squaresToMake_Y = []

        # making triangles

        for j in xrange(0, len(trianglesToMake_X)/2):

            print 'Iteration ' + str(i) + ' of ' + str(numberOfIterations) + '. Triangle ' + str(j) + ' of ' +  str(len(trianglesToMake_X)/2)
            k = j * 2
            newVertices_X, newVertices_Y = rotateShape([0, 1, 0.5], [0, 0, 0.5], trianglesToMake_X[k:k+2], trianglesToMake_Y[k:k+2])

            # merge x and y
            combinedVertices = zip(newVertices_X, newVertices_Y)

            # draw
            #print 'Drawing triangle:'
            #print combinedVertices
            draw.polygon(combinedVertices, fill = (redCurrent, greenCurrent, blueCurrent))

            squaresToMake_X.extend([newVertices_X[0], newVertices_X[2], newVertices_X[2], newVertices_X[1]])
            squaresToMake_Y.extend([newVertices_Y[0], newVertices_Y[2], newVertices_Y[2], newVertices_Y[1]])

            #print 'Squares to make:'
            #print zip(squaresToMake_X, squaresToMake_Y)

        trianglesToMake_X = []
        trianglesToMake_Y = []


        print '----------'

    img2=img.rotate(180)
    img2.show()

list
对象是可变的,因此当您将它们传递到函数中时,将传递对原始列表的引用,而不是副本。因此,当您修改列表时,例如使用
shapeXCoordinates[i]=newX
,您同时修改了原始列表

如果只希望修改保持函数的本地性,而不更改原始内容,则需要先复制列表:

shapeX = shapeXCoordinates[:]
然后在函数中的任何地方引用
shapeX
,而不是
shapeXCoordinates

显然,命名变量对您来说是有意义的