getter and setter and list appends

Discussion in 'Python' started by dasacc22, Apr 20, 2009.

  1. dasacc22

    dasacc22 Guest

    Hi,

    I seem to be having a problem with a list being share across multiple
    instantiations of it and dont quite understand why this is happening.

    My class looks like this,

    class Widget(object):
    _parent = None
    _children = []

    def __init__(self, parent=None):
    self.parent = parent

    @property
    def children(self):
    return self._children

    @property
    def parent(self):
    return self._parent

    @parent.setter
    def parent(self, obj):
    if obj:
    obj._children.append(self)
    self._parent = obj


    now if i make instances and attach children like so

    a = Widget()
    b = Widget(a)
    c = Widget(a)
    d = Widget(c)

    Basically all the objects end up sharing the _children list from `a`
    instead of forming something like a tree. Any advice would be greatly
    appreciated.

    Thanks,
    Daniel
    dasacc22, Apr 20, 2009
    #1
    1. Advertising

  2. dasacc22 wrote:

    > Hi,
    >
    > I seem to be having a problem with a list being share across multiple
    > instantiations of it and dont quite understand why this is happening.
    >
    > My class looks like this,
    >
    > class Widget(object):
    > _parent = None
    > _children = []
    >
    > def __init__(self, parent=None):
    > self.parent = parent
    >
    > @property
    > def children(self):
    > return self._children
    >
    > @property
    > def parent(self):
    > return self._parent
    >
    > @parent.setter
    > def parent(self, obj):
    > if obj:
    > obj._children.append(self)
    > self._parent = obj
    >
    >
    > now if i make instances and attach children like so
    >
    > a = Widget()
    > b = Widget(a)
    > c = Widget(a)
    > d = Widget(c)
    >
    > Basically all the objects end up sharing the _children list from `a`
    > instead of forming something like a tree. Any advice would be greatly
    > appreciated.


    The problem stems from you confusing instance attributes with class
    attributes. You use a latter, which is shared amongst *all* instances of a
    given class.

    If you want instance-attributes, use

    def __init__(self, ..):
    self.children = []

    also, your use of properties for the children is pointless in Python. Just
    use "children" as attribute name. Then, if at one fine day you want to do
    something more than just returning that value, you can still do that witout
    changing the interface by using a property - as you do so for parent.

    Diez
    Diez B. Roggisch, Apr 20, 2009
    #2
    1. Advertising

  3. dasacc22

    dasacc22 Guest

    Ah thank you for clarifying, I did confuse instance and class
    attributes from creating the list in the class def. I actually just
    spiffed up that class to represent a portion of a much larger class
    that needs getter and setter for children. Doing as you said fixed my
    problem, heres the code as reference for w/e

    class Widget(object):
    _children = None
    _parent = None

    def __init__(self, parent=None):
    self.children = []
    self.parent = parent

    @property
    def children(self):
    return self._children

    @children.setter
    def children(self, obj):
    self._children = obj

    @property
    def parent(self):
    return self._parent

    @parent.setter
    def parent(self, obj):
    if obj:
    print obj
    obj.children.append(self)
    self._parent = obj


    On Apr 20, 1:05 pm, "Diez B. Roggisch" <> wrote:
    > dasacc22 wrote:
    > > Hi,

    >
    > > I seem to be having a problem with a list being share across multiple
    > > instantiations of it and dont quite understand why this is happening.

    >
    > > My class looks like this,

    >
    > > class Widget(object):
    > >     _parent = None
    > >     _children = []

    >
    > >     def __init__(self, parent=None):
    > >         self.parent = parent

    >
    > >     @property
    > >     def children(self):
    > >         return self._children

    >
    > >     @property
    > >     def parent(self):
    > >         return self._parent

    >
    > >     @parent.setter
    > >     def parent(self, obj):
    > >         if obj:
    > >             obj._children.append(self)
    > >             self._parent = obj

    >
    > > now if i make instances and attach children like so

    >
    > > a = Widget()
    > > b = Widget(a)
    > > c = Widget(a)
    > > d = Widget(c)

    >
    > > Basically all the objects end up sharing the _children list from `a`
    > > instead of forming something like a tree. Any advice would be greatly
    > > appreciated.

    >
    > The problem stems from you confusing instance attributes with class
    > attributes. You use a latter, which is shared amongst *all* instances of a
    > given class.
    >
    > If you want instance-attributes, use
    >
    > def __init__(self, ..):
    >     self.children = []
    >
    > also, your use of properties for the children is pointless in Python. Just
    > use "children" as attribute name. Then, if at one fine day you want to do
    > something more than just returning that value, you can still do that witout
    > changing the interface by using a property - as you do so for parent.
    >
    > Diez
    dasacc22, Apr 20, 2009
    #3
  4. dasacc22

    Terry Reedy Guest

    dasacc22 wrote:
    > Hi,
    >
    > I seem to be having a problem with a list being share across multiple
    > instantiations of it and dont quite understand why this is happening.


    Class attributes are shared by all instances.

    > My class looks like this,
    >
    > class Widget(object):
    > _parent = None
    > _children = []


    Move this line
    >
    > def __init__(self, parent=None):
    > self.parent = parent


    to here.
    >
    > @property
    > def children(self):
    > return self._children
    >
    > @property
    > def parent(self):
    > return self._parent
    >
    > @parent.setter
    > def parent(self, obj):
    > if obj:
    > obj._children.append(self)
    > self._parent = obj
    >
    >
    > now if i make instances and attach children like so
    >
    > a = Widget()
    > b = Widget(a)
    > c = Widget(a)
    > d = Widget(c)
    >
    > Basically all the objects end up sharing the _children list from `a`
    > instead of forming something like a tree. Any advice would be greatly
    > appreciated.
    >
    > Thanks,
    > Daniel
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    Terry Reedy, Apr 20, 2009
    #4
  5. >>>>> dasacc22 <> (d) wrote:

    >d> Ah thank you for clarifying, I did confuse instance and class
    >d> attributes from creating the list in the class def. I actually just
    >d> spiffed up that class to represent a portion of a much larger class
    >d> that needs getter and setter for children. Doing as you said fixed my
    >d> problem, heres the code as reference for w/e


    >d> class Widget(object):
    >d> _children = None
    >d> _parent = None


    You still have them as class variables here. Now they are only used as
    defaults because you assign to them in the instances so the instance
    variables will be created then. But I think it is still confusing to
    have these class variables here that you never use as such. Maybe this
    is some leftover from Java experience where you do declare instance
    variables at the class level?

    >d> def __init__(self, parent=None):
    >d> self.children = []
    >d> self.parent = parent


    >d> @property
    >d> def children(self):
    >d> return self._children


    >d> @children.setter
    >d> def children(self, obj):
    >d> self._children = obj


    What is the added value of using a property for the children attribute?
    Why not just use an instance variable directly? Also a Java inheritance?

    --
    Piet van Oostrum <>
    URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
    Private email:
    Piet van Oostrum, Apr 24, 2009
    #5
  6. dasacc22

    dasacc22 Guest

    On Apr 24, 4:04 am, Piet van Oostrum <> wrote:
    > >>>>> dasacc22 <> (d) wrote:

    > >d> Ah thank you for clarifying, I did confuse instance and class
    > >d> attributes from creating the list in the class def. I actually just
    > >d> spiffed up that class to represent a portion of a much larger class
    > >d> that needs getter and setter for children. Doing as you said fixed my
    > >d> problem, heres the code as reference for w/e
    > >d> class Widget(object):
    > >d>     _children = None
    > >d>     _parent = None

    >
    > You still have them as class variables here. Now they are only used as
    > defaults because you assign to them in the instances so the instance
    > variables will be created then. But I think it is still confusing to
    > have these class variables here that you never use as such. Maybe this
    > is some leftover from Java experience where you do declare instance
    > variables at the class level?
    >
    > >d>     def __init__(self, parent=None):
    > >d>         self.children = []
    > >d>         self.parent = parent
    > >d>     @property
    > >d>     def children(self):
    > >d>         return self._children
    > >d>     @children.setter
    > >d>     def children(self, obj):
    > >d>         self._children = obj

    >
    > What is the added value of using a property for the children attribute?
    > Why not just use an instance variable directly? Also a Java inheritance?
    >
    > --
    > Piet van Oostrum <>
    > URL:http://pietvanoostrum.com[PGP 8DAE142BE17999C4]
    > Private email:


    Hi, yes, you are right, this is from previous experience, and thank
    you for bringing this out. It would be better suited to move those
    class variables to a comment to stay comfortable perhaps or eliminate
    them altogether.

    The property method of parent and children actually calls a
    _set_as_parent() and _set_as_child() method after setting the private
    variable to pack the object for display purposes so that children can
    be detached from the parent (becoming its own parent) as a gui event.
    dasacc22, Apr 24, 2009
    #6
  7. >>>>> dasacc22 <> (d) wrote:

    >d> The property method of parent and children actually calls a
    >d> _set_as_parent() and _set_as_child() method after setting the private
    >d> variable to pack the object for display purposes so that children can
    >d> be detached from the parent (becoming its own parent) as a gui event.


    Oh, I saw that in the parent setter but not in the children setter.
    --
    Piet van Oostrum <>
    URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
    Private email:
    Piet van Oostrum, Apr 25, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Adam Sandler

    problem with getter and setter not working

    Adam Sandler, May 25, 2006, in forum: ASP .Net
    Replies:
    12
    Views:
    715
    Jimi200478
    May 26, 2006
  2. Steve
    Replies:
    1
    Views:
    242
  3. Brian Bruggeman

    @property simultaneous setter and getter

    Brian Bruggeman, Dec 20, 2013, in forum: Python
    Replies:
    4
    Views:
    62
    Terry Reedy
    Dec 21, 2013
  4. Peter Otten
    Replies:
    0
    Views:
    237
    Peter Otten
    Dec 21, 2013
  5. Devin Jeanpierre

    Re: @property simultaneous setter and getter

    Devin Jeanpierre, Dec 21, 2013, in forum: Python
    Replies:
    0
    Views:
    249
    Devin Jeanpierre
    Dec 21, 2013
Loading...

Share This Page