(Python 2.7) Переменная доступа из класса с помощью метода доступа / мутатора - PullRequest
0 голосов
/ 02 ноября 2018

(Python 2.7) Я пытаюсь получить доступ к переменной vertices из класса SierpinskiTriangle и использовать ее во втором приведенном фрагменте кода, но он показывает

TypeError: объект 'property' не повторяется

Я могу только предположить, что это из-за аксессоров / мутаторов

Базовый код:

class Fractal(object):

# the constructor
def __init__(self, dimensions):
    # the canvas dimensions
    self.dimensions = dimensions
    # the default number of points to plot is 50,000
    self.num_points = 50000
    # the default distance ratio is 0.5 (halfway)
    self.r = 0.5

# accessors and mutators
@property
def vertices(self):
    return self._vertices

@vertices.setter
def vertices(self, v):
    self._vertices = v


class SierpinskiTriangle(Fractal):
# the constructor
def __init__(self, canvas):
    # call the constructor in the superclass
    Fractal.__init__(self, canvas)
    # define the vertices based on the fractal size
    v1 = Point(self.dimensions["mid_x"], self.dimensions["min_y"])
    v2 = Point(self.dimensions["min_x"], self.dimensions["max_y"])
    v3 = Point(self.dimensions["max_x"], self.dimensions["max_y"])
    self.vertices = [ v1, v2, v3 ]

Код для получения вершин в:

class ChaosGame(Canvas):

vertex_radius = 2
vertex_color = "red"
point_radius = 0
point_color = "black"

def __init__(self, master):
    Canvas.__init__(self, master, bg = "white")
    self.pack(fill = BOTH, expand = 1)

# a function that takes a string that represents the fractal to create
def make(self, f):
    if f == "SierpinskiTriangle":
        vertices = SierpinskiTriangle.vertices
    if f == "SierpinskiCarpet":
        vertices = []
    if f == "Pentagon":
        vertices = []
    if f == "Hexagon":
        vertices = []
    if f == "Octagon":
        vertices = []

    print vertices
    for point in vertices:
        self.plot_point(self, point, ChaosGame.vertex_color, ChaosGame.vertex_radius)

1 Ответ

0 голосов
/ 02 ноября 2018

Это потому, что вы обращаетесь к классу, а не к объекту этого типа.

Давайте попробуем это на минимальном примере:

class Container:
    def __init__(self):
        self._content = range(10)

    @property
    def content(self):
        return self._content

    @content.setter
    def set_content(self, c):
        self._content = c

Это работает:

c = Container()
for number in c.content:
    print(number)

(распечатывает числа от 0 до 9).

Но это не удалось:

for number in Container.content:
    print(number)

с ошибкой

TypeError        Traceback (most recent call last)
<ipython-input-27-f1df89781355> in <module>()
      1 # This doesn't:
----> 2 for number in Container.content:
      3     print(number)

TypeError: 'property' object is not iterable

Помимо проблем со свойствами, вы не инициализировали объект, поэтому функция класса __init__ никогда не вызывалась, а Container._content не инициализировалась.

На самом деле, у вас возникла бы аналогичная проблема, если бы вы только что использовали

class Container:
    def __init__(self):
        self.container = range(10)

(только в этом случае это будет ошибкой атрибута). Конечная нота: это

for number in Container().content:  # note the '()'!!
    print(number)

снова работает, потому что мы создаем объект контейнера на лету.

...