On Monday, June 10, 2013 8:18:52 AM UTC-5, Rui Maciel wrote:
> [...]
>
> <code> 
> class Point:
>         position = []
>         def __init__(self, x, y, z = 0):
>                 self.position = [x, y, z]

Firstly. Why would you define a Point object that holds it's x,y,z values in a 
list attribute? Why not store them as self.x, self.y and self.z? But if you are 
going to store them as a list, then why not extend a python list? I hate to see 
a "listy" object that only holds a list. It begs the question: Why not make it 
a *real* list? (Although i believe the former approach is more desirable for 
this problem)

Secondly, why would store the position of the Point as a class attribute? Do 
you realize that EVERY instance of the Point object will share the same x,y, 
and z values if you do it that way? (considering you query the correct variable 
*evil grin*)

Actually, you have a legitimate excuse: you were fooled because in your "object 
definition" you declared a "class level variable" named "position". THEN in 
your "__init__" method you declared an "instance level variable" named 
"position". 

Then, when you assigned the x,y,z values to "self.position" you thought you 
where assigning them to the "class level variable" named "position", HaHa, but 
then again you had NO idea that "class level variables" and "instance level 
variables" even existed! (or, at least, how to properly declare them)

Q: Yes Rick but how do i solve this issue?

By changing the names we can inspect the Point object and understand how class 
level and instance level variables work in Python. Observe:

## START SESSION ##
py> class Foo(object):
...     classVar = []
...     def __init__(self, arg):
...         self.instanceVar = arg
... 
py> Foo.classVar
[]
py> Foo.classVar = "apple"
py> Foo.classVar
apple
py> foo1 = Foo("pear")
py> foo1.classVar
apple
py> foo1.instanceVar
pear
py> foo2 = Foo("peach")
py> foo2.classVar
apple
py> foo2.instanceVar
peach
## END SESSION ##

As you can see the "class level variable" is known to all instances of the 
object, and a change in one is equal to a change in all. Whereas the "instance 
level variables" are unique to each instance.

> class Line:
>         points = ()
>         def __init__(self, p_i, p_f):
>                 self.points = (p_i, p_f)

Same problem here with the class level/instance level thing.

> It would be nice if, whenever a Point object was updated,
> the Line objects which are associated with it could
> reflect those updates directly in Line.p_i and Line.p_f.
> What's the Python way of achieving the same effect? Thanks
> in advance, Rui Maciel
> 

If you construct your code properly this can be achieved. If each point is an 
object, and lines are merely holding references to two point objects that 
define the start and end position of an imaginary "line", then updates on the 
points will be reflected in the Line object. 

Observe:

## START SESSION ##
py> class Point3d(object):
...     def __init__(self, x, y, z):
...         self.x = x
...         self.y = y
...         self.z = z
...     def __str__(self):
...         _ = 'Point3d({}, {}, {})'
...         return _.format(self.x, self.y, self.z)
...         
py> p1 = Point3d(1,2,3)
py> str(p1)
Point3d(1, 2, 3)
py> p2 = Point3d(3,4,5)
py> str(p2)
Point3d(3, 4, 5)
py> class Line3d(object):
...     def __init__(self, p1, p2):
...         self.p1 = p1
...         self.p2 = p2
...     def __str__(self):
...         _ = 'Line3d({}, {})'
...         return _.format(self.p1, self.p2)
...         
py> line1 = Line3d(p1, p2)
py> str(line1)
Line3d(Point3d(1, 2, 3), Point3d(3, 4, 5))
py> p1.x = 100
py> str(p1)
Point3d(100, 2, 3)
py> str(line1)
Line3d(Point3d(100, 2, 3), Point3d(3, 4, 5))
## END SESSION ##

Easy peasy.
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to