Class Encapsulation Errors in Python 2.3.3

Dan Perl danperl at rogers.com
Fri Nov 19 15:32:20 EST 2004


I fully agree with Jeff and I will make a couple of other small points.

I saw you meant to use 'False' as a default value for the class-level 
attribute 'songs'.  'None' is the normal value for initializations like 
that.  It's a small point but it kind of stuck in my mind as being unusual.

If you still choose to use class-level attributes and to initialize them 
with default values, you have to keep in mind that you will encounter this 
kind of problem with all the initializations that are using complex types. 
That means lists like in the case of 'songs', but also strings like in the 
case of 'name' and 'artist'.  Jeff pointed out in an earlier posting that 
there are also other ways you could get into trouble like this and it should 
be made clear that this is true for all the complex types, not only lists.

Dan

"Jeff Shannon" <jeff at ccvcorp.com> wrote in message 
news:10pskhnjt2met3f at corp.supernews.com...
> Tim Henderson wrote:
>
>>Here is a partial implementation, i don't have the code with me but
>>this is how the songs list is made
>>
>>code:
>>-------------------------------------------
>>class Album:
>>    name = ''
>>    songs = []
>>    artist = ''
>>
>>    def __init__(self, name, artist):
>>        self.name = name
>>        self.artist = artist
>>-------------------------------------------
>>
>
> Yes, this gives you class-level attributes, shared by all instances of 
> Album.  In the case of name and artist, you're then creating 
> instance-level attributes ('self.name = name') which shadow the 
> class-level attribute.  But you never bind 'songs' on the instance, so 
> you're just modifying the class-level (shared) songs list.
>
>>after reading the code i came up with a possible solution:
>>
>>possible code:
>>-------------------------------------------
>>class Album:
>>    name = ''
>>    songs = False
>>    artist = ''
>>
>>    def __init__(self, name, artist):
>>        self.name = name
>>        self.artist = artist
>>        if songs == False:
>>            songs = []
>>------------------------------------------
>>
>
> That'll almost work -- within __init__(), you need to refer to songs as 
> self.songs (both times).  But why bother with creating the class-level 
> attributes?  If you just set them in __init__(), all will be fine.
>
> class Album:
>
>    def __init__(self, name, artist):
>
>        self.name = name
>        self.artist = artist
>        self.songs = []
>
> will have the same net effect as your code, for the vast majority of 
> common purposes.  (There are corner cases where having class-level 
> defaults is helpful, but I sincerely doubt that this is true for your 
> program.)
>
> Jeff Shannon
> Technician/Programmer
> Credit International
>
> 





More information about the Python-list mailing list