Class Encapsulation Errors in Python 2.3.3

Dan Perl danperl at rogers.com
Fri Nov 19 21:36:15 CET 2004


Errata: instead of "complex types" please read "mutable types".

"Dan Perl" <danperl at rogers.com> wrote in message 
news:z_ydneo0T-HFxQPcRVn-ug at rogers.com...
>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