Class Encapsulation Errors in Python 2.3.3

Dan Perl danperl at rogers.com
Fri Nov 19 17:05:10 EST 2004


Better make another correction before someone else totally embarrasses me. 
I was wrong, strings are not mutable.

That immediately made me wonder why strings are immutable.  But it turns out 
that question has already been beaten to death, not too long ago 
(http://groups.google.com/groups?hl=en&lr=&c2coff=1&threadm=DbqdnXN8NqpMxrfcRVn-pw%40comcast.com&rnum=2&prev=/groups%3Fq%3Dmutable%2Bstring%2Bimmutable%26hl%3Den%26lr%3D%26group%3Dcomp.lang.python.*%26c2coff%3D1%26selm%3DDbqdnXN8NqpMxrfcRVn-pw%2540comcast.com%26rnum%3D2)

Dan

"Dan Perl" <danperl at rogers.com> wrote in message 
news:06adnWRWPNfexAPcRVn-gA at rogers.com...
> 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