This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ekarademir
Recipients ekarademir
Date 2017-11-29.11:15:04
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1511954104.7.0.213398074469.issue32168@psf.upfronthosting.co.za>
In-reply-to
Content
Hello,

I've searched all over Google and this bug tracker with all combinations of keywords that I can associate with this issue, but I couldn't find an explanation that makes sense or fits the issue.

I know that when dealing with mutable variables, class variables share the same reference with all instances, so to assign separate attributes for instances, mutable variables should be instance level variables.

However when I create a class like the following,

    class Base:
        def __init__(self, props=list(), foo='foo base'):
            self.props = props
            self.foo = foo
        
        def insert_prop(self, i):
            self.props.append(i)

and run this:

    if __name__ == '__main__':
        base = Base()

        base.insert_prop(1)
        base.insert_prop(2)

        print('base props before base2, 3 creation:', base.props)

        base2 = Base()
        base3 = Base([41, 42])

        print('base props after base2, 3 creation:', base.props)
        print('base2 props after base2, 3 creation:', base2.props)
        print('base3 props after base2, 3 creation:', base3.props)

        base2.insert_prop(51)
        base3.insert_prop(61)

        print('base props after insertion:', base.props)
        print('base2 props after insertion:', base2.props)
        print('base3 props after insertion:', base3.props)

the output is this:

    base props before base2, 3 creation: [1, 2]
    base props after base2, 3 creation: [1, 2]
    base2 props after base2, 3 creation: [1, 2]
    base3 props after base2, 3 creation: [41, 42]
    base props after insertion: [1, 2, 51]
    base2 props after insertion: [1, 2, 51]
    base3 props after insertion: [41, 42, 61]

So initiating base3 with explicit args gives it a new reference to the props variable but base and base2 share the same reference. So suddenly props is hoisted to class level.

I actually encountered this behaviour when trying to do the same thing with child classes with no __init__ method like:

    class Sub1(Base):
        pass

The whole code is attached.

Is this an expected behaviour? If so I couldn't find a gotcha anywhere.

Regards,

Ertugrul
History
Date User Action Args
2017-11-29 11:15:04ekarademirsetrecipients: + ekarademir
2017-11-29 11:15:04ekarademirsetmessageid: <1511954104.7.0.213398074469.issue32168@psf.upfronthosting.co.za>
2017-11-29 11:15:04ekarademirlinkissue32168 messages
2017-11-29 11:15:04ekarademircreate