Python在处理中的类声明中的@property等价物?

时间:2015-12-22 18:11:59

标签: java python class processing processing.js

在寒假回家的时候,我将尝试使用Processing编程语言(Java风格)制作一些很酷的东西。对于我的第一个项目,我想定义一个自定义Line类,以便更容易在线上进行数学运算。在python中,它将是这样的:

import numpy as np

class Line():
    def __init__(self, x1, y1, x2, y2):
        self.x1, self.x2 = x1, x2
        self.y1, self.y2 = y1, y2

    @property
    def p1(self):
        return np.array([self.x1, self.y1])

    @property
    def p2(self):
        return np.array([self.x2, self.y2])

这样,如果改变x1,...,y2,那么对应的点矢量也是如此。显然这个例子效率有点低,但重点仍然存在。在javascript中,我知道Object.defineProperty(obj, prop, descriptor),但不清楚

  • 如何在处理中执行此操作
  • 这里发挥作用。在定义类时,等效操作是什么?

修改:澄清为什么@property特别有用:

假设我希望用两种方式表示这两行,这两种方式都将由Line对象存储:

  • 一,香草版:两个点,p1和p2,每个点由x,y坐标组成。
  • 两个带有两个点u和v的参数化版本,使得p1 = u和p2 = u + v,线段上的任何点由u + t * v给出,其中t是0和0之间的标量1.

如果p2改变了,那将改变v,反之亦然。更改p1将同时改变u和v。有些数学在参数化版本方面更容易做,有些在vanilla版本方面更容易做,所以我希望对任何属性进行的任何更改都能正确更新其他属性,使p1,p2和u,v始终表示相同的行。

在python中,我可以修改属性的setter和getter方法来适当地考虑所有这些,但我似乎无法确定在Processing中执行此操作的方法。

1 个答案:

答案 0 :(得分:1)

如果你只使用常规的处理对象和语法,那么你会非常自动地得到它。

例如,您可以使用两个PVector实例来定义端点。

class Line{
   PVector p1;
   PVector p2;

   public Line(float x1, float y1, float x2, float y2){
      p1 = new PVector(x1, y1);
      p2 = new PVector(x2, y2);
   }
}

然后,如果您想更改其中一个端点,您可以直接访问PVector个实例:

Line myLine = new Line(0, 10, 25, 100);
println(myLine.p1.x + ", " myLine.p1.y);
myLine.p1.x = 750;
println(myLine.p1.x + ", " myLine.p1.y);

您还可以获得PVector class中已定义的所有数学内容。

您可以通过将PVector变量设为最终变量或仅允许Line类的用户通过然后访问PVector实例的setter更改端点来更好地“保护”PVector变量。 / p>

修改:我将在此处尝试回答您的其他问题。

  

是公众必要的吗?

这取决于您使用此课程的具体方式,您希望其他人如何访问该课程等。您可以在the Processing reference中了解相关内容,或者只是谷歌“java access modifiers” ”。或者你可以试着把它拿出去看看会发生什么。

  

如果我同时想要一条线(x1,y1,x2,y2)和参数化(u1,u2,v1,v2,st x1 = u1和x2 = u1 + v1等)版本的香草定义怎么办? ?在这种情况下,重要的是,如果更新了x2,那么v1也应该更新。

我不确定你在这里问的是什么。在编写课程时,您可以决定如何代表您的州如何让人们与该州进行互动

例如,我上面的示例使用两个class Line{ PVector p1; PVector p2; public Line(float x1, float y1, float x2, float y2){ p1 = new PVector(x1, y1); p2 = new PVector(x2, y2); } public Line(PVector origin, float angle, float distance){ p1 = origin; p2 = new PVector(origin.x + cos(angle)*distance, origin.y + sin(angle)*distance); } } 实例来表示该行,它允许人们直接与它们交互以修改该行。但我可以添加一个函数,让他们将一条线定义为一个点,一个角度和一个距离。我只需要确保计算第二点,这样我就可以存储我的状态。像这样:

PVector

请注意,第二个构造函数允许用户以完全不同的方式指定一行,但我仍然将我的状态存储为两个angle实例。如果您以后需要,可以存储distancePVector值,并且您可以设置允许用户修改它们的设置器 - 您只需相应地更新DATA INPUTS; infile cards dlm=',' dsd; INPUT DOBDt :DATE9. EvalDt :DATE9. expected; FORMAT DOBDt date9. EvalDt date9.; age = year(evaldt)-year(dobdt) - (month(evaldt) eq month(dobdt) and day(evaldt) lt day(dobdt)) - (month(evaldt) lt month(dobdt)); CARDS; 11MAY2009,10MAY2015,5 11MAY2009,11MAY2015,6 11MAY2009,12MAY2015,6 28FEB1984,01DEC2015,31 29FEB1984,28FEB2012,27 29FEB1984,29FEB2012,28 29FEB1984,01MAR2012,28 ;;;; RUN; proc print; run; 值。 / p>