473,734 Members | 2,511 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Class Encapsulation Errors in Python 2.3.3

Hi i have some errors in my code that i can't find the reason for here
is the error

i have 3 classes:
-Song
-Album
-Artist

Song has 3 pieces of data with getter and setter meathods:
-Name | i.e. song name
-Album
-Artist

Album has 3 pieces of data:
-Songs | a list of Song() instances
-Name
-Artist

Artist has 4 pieces of Data:
-Name
-Songs | a list of Song() instances
-Albums |a list of Album() instances
-unknownAlbum | the album a song is put into if it doesn't have an
album
now the problem arises when i add songs into multiple albums like
this:
Code:
------------------------------------------------
s = Song('song 1')
s2 = Song('song 2')

a = Album('hey')
a.addSong(s)
ab = Album('yeayea')
print a
print ab
ab.addSong(s2)
print
print a
print ab
------------------------------------------------
Output:
*************** *************** *************** ***
hey song 1 hey |
yeayea song 1 hey |

hey song 1 hey | song 2 yeayea |
yeayea song 1 hey | song 2 yeayea |
*************** *************** *************** ***

the "hey" album has "song 1" as it is suppose to however so does
"yeayea" even though when "song 1" was put in the album "hey" 'yeayea'
didn't even exist yet.

Why is this happening. I checked the actually memory refrence for each
instance and they are different, these supposidly isolated different
intances of clases are linked for some inexplicable reason.

Does any one know why this is happening and how i can fix it?

cheers
Tim Henderson
Jul 18 '05 #1
15 1445
Tim Henderson wrote:
Hi i have some errors in my code that i can't find the reason for here
is the error
[...]
the "hey" album has "song 1" as it is suppose to however so does
"yeayea" even though when "song 1" was put in the album "hey" 'yeayea'
didn't even exist yet.


I can think of two likely reasons offhand.

The first is that you're storing the songlist as a class attribute,
rather than as an instance attribute. The second is that you're using a
mutable default value in a method call. (I'm guessing that it's
probably this second reason.)

Do you have something like this?

class Album:
def __init__(self, songs=[]):
self.songs = songs
# ...

The problem here is that default values in functions/methods are
evaluated at *compile* time. That means that this creates a single
empty list, which is used as the default value for *every* Album
instance. When you mutate that list, then every instance with a
reference to that list shows the changes.

The other possibility (class attribute rather than instance attribute)
would happen if you have something like this:

class Album:
songs = []
def __init__(self, ...):
# ...

In this case, again, you have a single empty list that will end up being
shared by all Album instances.

What you probably want to do in this case is this:

class Album:
def __init__(self, songs=None)
if songs is None:
songs = []
self.songs = songs
# ...

This will allow you to have an optional songs parameter in the
initializer, but still ensure that every instance gets an independent
empty list if nothing's passed in.

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #2
Tim Henderson wrote:

<snip>

now the problem arises when i add songs into multiple albums like
this:
Code:
------------------------------------------------
s = Song('song 1')
s2 = Song('song 2')

a = Album('hey')
a.addSong(s)
ab = Album('yeayea')
print a
print ab
ab.addSong(s2)
print
print a
print ab
------------------------------------------------
Output:
*************** *************** *************** ***
hey song 1 hey |
yeayea song 1 hey |

hey song 1 hey | song 2 yeayea |
yeayea song 1 hey | song 2 yeayea |
*************** *************** *************** ***

<snip>

Defnition of addSong() would help in determining the real cause. Taking
a guess here but it looks like the 'list' you store the songs in is
shared across all albums. Typically this happens if you define the list
in the class itself making it a class attribute - and not in __init__().
Please show us the code of Album to help you further.

Shalabh

Jul 18 '05 #3
Please post the implementation of the Album class. The problem is coming
probably from the way the Songs list is defined or initialized. That is,
the definition or the initialization probably cause the list object that is
assigned to Songs to be shared by all the Album instances. But I (and
likely no one else) can say exactly what the problem is without seing the
code.

Dan

"Tim Henderson" <ti******@gmail .com> wrote in message
news:47******** *************** ***@posting.goo gle.com...
Hi i have some errors in my code that i can't find the reason for here
is the error

i have 3 classes:
-Song
-Album
-Artist

Song has 3 pieces of data with getter and setter meathods:
-Name | i.e. song name
-Album
-Artist

Album has 3 pieces of data:
-Songs | a list of Song() instances
-Name
-Artist

Artist has 4 pieces of Data:
-Name
-Songs | a list of Song() instances
-Albums |a list of Album() instances
-unknownAlbum | the album a song is put into if it doesn't have an
album
now the problem arises when i add songs into multiple albums like
this:
Code:
------------------------------------------------
s = Song('song 1')
s2 = Song('song 2')

a = Album('hey')
a.addSong(s)
ab = Album('yeayea')
print a
print ab
ab.addSong(s2)
print
print a
print ab
------------------------------------------------
Output:
*************** *************** *************** ***
hey song 1 hey |
yeayea song 1 hey |

hey song 1 hey | song 2 yeayea |
yeayea song 1 hey | song 2 yeayea |
*************** *************** *************** ***

the "hey" album has "song 1" as it is suppose to however so does
"yeayea" even though when "song 1" was put in the album "hey" 'yeayea'
didn't even exist yet.

Why is this happening. I checked the actually memory refrence for each
instance and they are different, these supposidly isolated different
intances of clases are linked for some inexplicable reason.

Does any one know why this is happening and how i can fix it?

cheers
Tim Henderson

Jul 18 '05 #4
Jeff Shannon wrote:
The problem here is that default values in functions/methods are
evaluated at *compile* time.


Actually, no. The default values in functions/methods are evaluated when
the def statement is *executed* not when anything is compiled. If you
execute the def multiple times the default values are recalculated each
time.
Jul 18 '05 #5
On 19 Nov 2004 10:44:56 GMT, Duncan Booth <du**********@i nvalid.invalid> wrote:
Jeff Shannon wrote:
The problem here is that default values in functions/methods are
evaluated at *compile* time.


Actually, no. The default values in functions/methods are evaluated when
the def statement is *executed* not when anything is compiled. If you
execute the def multiple times the default values are recalculated each
time.


Be careful :-) default values are calculated when the def statement is
executed.... which is not the same as to say that they are calculated
every time the function is called.

To explain it better. In a conventional Python program, the def
statement is executed only once, when a module is loaded, for example.
In this case, default values are stored as attributes of the function
object. In this case, the value of the default never changes.

*If* for some reason your code runs over the def statement multiple
times, *then* a new function object will be created with new default
values. For example, this can happen if you force-reload a module, or
def the function inside a for loop (weird but it works):

for i in (1,2,3):
def print_i(x=i):
print x,i
print_i() 3 3 i = 0
print_i()

3 0

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmai l.com
mail: ca********@yaho o.com
Jul 18 '05 #6
> On 19 Nov 2004 10:44:56 GMT, Duncan Booth <du**********@i nvalid.invalid>
wrote: > Jeff Shannon wrote: > > > The problem here is that default values
in functions/methods are > > evaluated at *compile* time. > > Actually,
no. The default values in functions/methods are evaluated when > the def
statement is *executed* not when anything is compiled. If you > execute
the def multiple times the default values are recalculated each > time.

Be careful :-) default values are calculated when the def statement is
executed.... which is not the same as to say that they are calculated
every time the function is called.

<rest of explanation snipped>

I actually thought I had stated the case fairly clearly, but I
suppose understanding what you think you have said isn't the same as
communicating it to the audience. :)
--
Duncan Booth
du**********@su ttoncourtenay.o rg.uk
Jul 18 '05 #7
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
-------------------------------------------

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 = []
------------------------------------------
i will test this when i get home, and update the thread with results

cheers
Tim Henderson

"Dan Perl" <da*****@rogers .com> wrote in message news:<nr******* *************@r ogers.com>...
Please post the implementation of the Album class. The problem is coming
probably from the way the Songs list is defined or initialized. That is,
the definition or the initialization probably cause the list object that is
assigned to Songs to be shared by all the Album instances. But I (and
likely no one else) can say exactly what the problem is without seing the
code.

Dan

"Tim Henderson" <ti******@gmail .com> wrote in message
news:47******** *************** ***@posting.goo gle.com...
Hi i have some errors in my code that i can't find the reason for here
is the error

i have 3 classes:
-Song
-Album
-Artist

Song has 3 pieces of data with getter and setter meathods:
-Name | i.e. song name
-Album
-Artist

Album has 3 pieces of data:
-Songs | a list of Song() instances
-Name
-Artist

Artist has 4 pieces of Data:
-Name
-Songs | a list of Song() instances
-Albums |a list of Album() instances
-unknownAlbum | the album a song is put into if it doesn't have an
album
now the problem arises when i add songs into multiple albums like
this:
Code:
------------------------------------------------
s = Song('song 1')
s2 = Song('song 2')

a = Album('hey')
a.addSong(s)
ab = Album('yeayea')
print a
print ab
ab.addSong(s2)
print
print a
print ab
------------------------------------------------
Output:
*************** *************** *************** ***
hey song 1 hey |
yeayea song 1 hey |

hey song 1 hey | song 2 yeayea |
yeayea song 1 hey | song 2 yeayea |
*************** *************** *************** ***

the "hey" album has "song 1" as it is suppose to however so does
"yeayea" even though when "song 1" was put in the album "hey" 'yeayea'
didn't even exist yet.

Why is this happening. I checked the actually memory refrence for each
instance and they are different, these supposidly isolated different
intances of clases are linked for some inexplicable reason.

Does any one know why this is happening and how i can fix it?

cheers
Tim Henderson

Jul 18 '05 #8
Duncan Booth wrote:
Jeff Shannon wrote:
The problem here is that default values in functions/methods are
evaluated at *compile* time.


Actually, no. The default values in functions/methods are evaluated when
the def statement is *executed* not when anything is compiled. If you
execute the def multiple times the default values are recalculated each
time.


Hm, true, I misspoke. Perhaps it's clearest to say that the default
values are evaluated when the function/method object is *created*, not
when it is called.

Functions are created when the def statement is executed; this is
usually one of the first things that happens when a simple module/script
is imported/run, but it can happen at other times as well. Referring to
the creation of function objects as compilation, as I did, is
technically inaccurate (compilation being the conversion of text source
code to bytecode, which is later executed). I do know the difference,
but tend to conflate them out of laziness in cases where the distinction
has little practical difference. (In this case, practical differences
are usually only significant when function/class definitions are dynamic
and/or some sort of deep magic is being employed, neither of which are
typical for me to need...) But I should indeed be more careful about
how I state that, because while *I* know what I meant, it doesn't follow
that someone else reading this and looking for guidance won't get bitten
by my laziness. :)

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #9
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
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2112
by: Florian Preknya | last post by:
Is there a posibility to overwrite a private method (one that starts with __ ) ? I read that they are just formely private, they are prefixed with the class name to have an obtured visibility, so maybe it's a trick here... More details... I use wxPython, more specifically the wxColumnSorterMixin class. I want to overwrite the __OnColClick event handler to behave on my way: I want the sorting feature will affect only some columns, not all...
15
2485
by: beliavsky | last post by:
What are the pros and cons of defining a method of a class versus defining a function that takes an instance of the class as an argument? In the example below, is it better to be able to write z.modulus() or modulus(z)? Is there a difference between Python and C++ in this regard? from math import sqrt class xy: def __init__(self,x,y): self.x = x
11
9604
by: Sean Don | last post by:
Hello! Is it possible to make classes friends in Python? Or is it better to just stick to "Java style" .isThis, .getThat, .setThis style functions? I understand that classes are generally grouped logically into separate files anyway. So, this isn't always necessary. But I'm a perfectionist and was wondering if friendships were possible in Python. Thank you!
50
6361
by: Dan Perl | last post by:
There is something with initializing mutable class attributes that I am struggling with. I'll use an example to explain: class Father: attr1=None # this is OK attr2= # this is wrong def foo(self, data): self.attr1=data self.attr2.append(data) The initialization of attr1 is obviously OK, all instances of Father redefine it in the method foo. But the initialization of attr2 is wrong
0
1268
by: kanedatakeshi | last post by:
Hi folks! The problem is the following: I use Python 2.1 embedded in a C++ game engine. Some of the engines complexer objects (AI, game logic, etc.) use python classes that act as an extension of those "parent" C++-classes. The python classes are currently loaded on demand by their "parent" C++-instances, say if an enemy gets activated and starts running. I do
9
2451
by: Steven T. Hatton | last post by:
It was once suggested to me that I could accomplish much the same thing that modules would accomplish (if C++ had modules) by writing my entire program - except for main() - inside of a class. When it was suggested, I didn't take it very seriously, but I have recently begun wondering if it is an idea worth considering. I'm now trying to think of what fundamental differences might exist between namespace scope, and class scope. One that...
9
1802
by: Larry Woods | last post by:
I have a method in my base class that I want ALL derived classes to use. But, I find that I can create a "Shadow" method in my derived class that "overrides" the method in my base class. Can't figure out what attribute to put on the base class method to prevent this. TIA, Larry Woods
9
2358
by: Rudy | last post by:
Hello All! I'm a little confused on Public Class or Modules. Say I have a this on form "A" Public Sub Subtract() Dim Invoice As Decimal Dim Wage As Decimal Static PO As Decimal Invoice = CDec(txbInv.Text) Wage = CDec(txbTotWage.Text)
4
1701
by: Jack | last post by:
Hi, I have a class with a get-only public bool property. This is good because I want users of this class to ONLY READ it. So I've defined it thus: private bool _IsDirty; public bool IsDirty{ get{ return _IsDirty; } }
0
8946
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9310
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8186
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6735
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6031
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4550
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3261
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2724
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2180
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.