Class Encapsulation Errors in Python 2.3.3
Dan Perl
danperl at rogers.com
Fri Nov 19 15:36:15 EST 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