迭代Python 3中的对象

时间:2016-02-09 14:15:37

标签: python python-3.x object

我想将我的代码从结构形式重写为对象。此脚本包含两个类:Point包含xy的点,Curve包含Points的列表。我需要以正确的顺序获取此Points列表,因为我想绘制它。代码以结构形式工作,因此只有类的问题。 有一段最重要的代码:

# -*- coding: utf-8 -*-
__author__ = 'Piotr Michalski University of Wroclaw'
from turtle import *
import random
import math

def binomial(i, n):
    """Newton"""
    return math.factorial(n) / float(
        math.factorial(i) * math.factorial(n - i))

def bernstein(t, i, n):
    """Bernstein"""
    return binomial(i, n) * (t ** i) * ((1 - t) ** (n - i))

def bezier(t, points):
    """Calculating coordinates of bezier curve"""
    n = len(points) - 1
    x = y = 0
    for i, pos in enumerate(points):
        bern = bernstein(t, i, n)
        x += pos[0] * bern
        y += pos[1] * bern
    return x, y

def bezier_curve_range(n, points):
    """Amount of points on bezier curve"""
    for i in range(n):
        t = i / float(n - 1)
        yield bezier(t, points)

def init():
    """Screen, turtle etc"""
    global tur, screen, litery, krzywe
    tur = Turtle()
    screen = Screen()
    screen.title('Generowanie tekstu')
    screen.setup(width=1400, height=400, startx=20, starty=200)
    screen.setworldcoordinates(0,400,1400,-150)
    tur.hideturtle()

def calculatespace(x):
    """Changing max x during drawing curve"""
    global max_x
    if x > max_x:
        max_x = x

def paint_event(ksztalt, steps=80, colorofdot='lightblue', colorofbezier='black',
                colorofguideline='lightgray'):
    """Drawing function"""
    global tur, screen
    print('Zainicjowano rysowanie {0}.\nIlość kroków'
          ' {1}'.format(ksztalt,steps))

        #No i rysujemy

    controlPoints = ksztalt
    oldPoint = controlPoints[0]

    tur.pen(pensize=1, pencolor=colorofdot)
    tur.up()
    tur.goto(oldPoint[0], oldPoint[1])
    tur.down()
    tur.dot()
    tur.up()

    for point in controlPoints[1:]:
        tur.pen(pencolor=colorofguideline, speed=3)
        tur.goto(oldPoint[0], oldPoint[1])
        tur.down()
        tur.goto(point[0], point[1])
        tur.pen(pencolor=colorofdot)
        tur.dot()
        tur.up()
        oldPoint = point

    tur.pen(pensize= 2,pencolor=colorofbezier,speed=0)
    oldPoint=ksztalt[0]

    for point in bezier_curve_range(steps, controlPoints):
        tur.goto(oldPoint[0], oldPoint[1])
        tur.down()
        tur.goto(point[0], point[1])
        tur.up
        calculatespace(point[0])
        oldPoint = point

class point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __str__(self):
        return str((self.x,self.y))
    def __repr__(self):
        return repr((self.x,self.y))

class curve:
    def __init__(self, *points):
        self.ListOfPoints = []
        for p in points:
            self.ListOfPoints.append(p)
    def __str__(self):
        return str(self.ListOfPoints)
    def __repr__(self):
        return repr(self.ListOfPoints)
    def __iter__(self):
        return iter(self.ListOfPoints)

p1 = point(10, 20)
p2 = point(5, 15)
p3 = point(70, 100)

k1 = curve(p1, p2, p3)
print(enumerate(k1))
init()
paint_event(k1)

我有这个错误:

print(enumerate(k1))
TypeError: 'curve' object is not iterable

1 个答案:

答案 0 :(得分:1)

我只想使用一个普通的清单:

k1 = [p1,p2]
print(enumerate(k1))

...但是如果你真的死定了自己的集合类,那就实现一个__iter__方法。

class curve:
    def __init__(self, *points):
        self.ListOfPoints = []
        for p in points:
            self.ListOfPoints.append(p)
    def __str__(self):
        return str(self.ListOfPoints)
    def __repr__(self):
        return repr(self.ListOfPoints)
    def __iter__(self):
        return iter(self.ListOfPoints)

从你编辑过的代码中,看起来你现在正在获得TypeError: 'curve' object does not support indexing,我想再次强调没有理由自己创建自己的课程,如果你只是要像对待它一样列表。但是,如果你真的非常致力于为自己创造额外的工作而没有任何好处,那就实施__getitem__

class curve:
    def __init__(self, *points):
        self.ListOfPoints = []
        for p in points:
            self.ListOfPoints.append(p)
    def __str__(self):
        return str(self.ListOfPoints)
    def __repr__(self):
        return repr(self.ListOfPoints)
    def __iter__(self):
        return iter(self.ListOfPoints)
    def __getitem__(self, key):
        return self.ListOfPoints[key]

您可能必须实施其他一些方法,例如__len__,但此时我认为您可以弄清楚应该如何完成。