Is a list static when it's a class member?

G

glue

I have a class with a list member and the list seems to behave like
it's static while other class members don't. The code...

class A:
name = ""
data = []
def __init__(self, name):
self.name = name
def append(self, info):
self.data.append(info)
def enum(self):
for x in self.data:
print "\t%s" % x

a = A("A:")
print a.name
a.append("one")
a.append("two")
a.enum()
b = A("B:")
print b.name
b.append("horse")
b.append("bear")
b.enum()
print a.name
a.enum()

The output...
A:
one
two
B:
one
two
horse
bear
A:
one
two
horse
bear

How do i get:
A:
one
two
B:
horse
bear
A:
one
two

Thanks,

glue
 
A

Antoine De Groote

glue said:
I have a class with a list member and the list seems to behave like
it's static while other class members don't. The code...

class A:
name = ""
data = []
def __init__(self, name):
self.name = name
def append(self, info):
self.data.append(info)
def enum(self):
for x in self.data:
print "\t%s" % x

a = A("A:")
print a.name
a.append("one")
a.append("two")
a.enum()
b = A("B:")
print b.name
b.append("horse")
b.append("bear")
b.enum()
print a.name
a.enum()

The output...
A:
one
two
B:
one
two
horse
bear
A:
one
two
horse
bear

How do i get:
A:
one
two
B:
horse
bear
A:
one
two

Thanks,

glue


I can already tell you that this does it:

class A:
name = ""
def __init__(self, name):
self.data = []
self.name = name
def append(self, info):
self.data.append(info)
def enum(self):
for x in self.data:
print "\t%s" % x

Somebody else can explain the reason. I just don't wanna write something
that I'm not sure of. :)

Regards,
antoine
 
K

kath

glue said:
I have a class with a list member and the list seems to behave like
it's static while other class members don't. The code...

class A:
name = ""
data = []
def __init__(self, name):
self.name = name
def append(self, info):
self.data.append(info)
def enum(self):
for x in self.data:
print "\t%s" % x

a = A("A:")
print a.name
a.append("one")
a.append("two")
a.enum()
b = A("B:")
print b.name
b.append("horse")
b.append("bear")
b.enum()
print a.name
a.enum()

The output...
A:
one
two
B:
one
two
horse
bear
A:
one
two
horse
bear

How do i get:
A:
one
two
B:
horse
bear
A:
one
two

Thanks,

glue




hi,

try this,
class A:
def __init__(self, name):
self.name = name
self.data=[] # Define an array when you
instantiate an object.
def append(self, info):
#self.data=[]
self.data.append(info)
def enum(self):
for x in self.data:
print "\t%s" % x

a = A("A:")
print a.name
a.append("one")
a.append("two")
a.enum()
b = A("B:")
print b.name
b.append("horse")
b.append("bear")
b.enum()
print a.name
a.enum()
 
T

Tim Chase

class A:
name = ""
data = []
def __init__(self, name):
self.name = name
def append(self, info):
self.data.append(info)
def enum(self):
for x in self.data:
print "\t%s" % x
How do i get:
A:
one
two
B:
horse
bear
A:
one
two


class A:
name = ""
# data = [] # just move this line
def __init__(self, name): #
self.name = name #
self.data = [] # here
def append(self, info):
self.data.append(info)
def enum(self):
for x in self.data:
print "\t%s" % x


It will be given a "fresh" list upon each __init__ call.

-tkc
 
F

Fredrik Lundh

glue said:
I have a class with a list member and the list seems to behave like
it's static while other class members don't. The code...

*all* class attributes are shared by all instances. however, instance
attributes hide class attributes with the same name.

in your case, you're hiding the "name" class attribute by creating an
instance attribute with the same name in the "__init__" method, but
you're modifying the shared "data" attribute in the "append" method.

if you want separate instances to use separate objects, make sure you
create new objects for each new instance. see Tim's reply for how to
do that.

class A:
name = ""
data = []
def __init__(self, name):
self.name = name
def append(self, info):
self.data.append(info)
def enum(self):
for x in self.data:
print "\t%s" % x
 
B

Ben Finney

glue said:
I have a class with a list member and the list seems to behave like
it's static while other class members don't.

It's not "static"; rather, it's a class attribute, by virtue of being
bound when the class is defined. Those are shared by all instances of
the class.
The code...

class A:
name = ""
data = []

This runs when the class is defined, creates two new objects and binds
them to the attribute names "name" and "data". All instances will
share both of these unless they re-bind the names to some other
object.
def __init__(self, name):
self.name = name

This defines a function that runs on initialisation of a new instance
of the class, and re-binds the attribute name "name" to the object
passed as the second parameter to __init__.

The binding that occurred when the class was defined is now
irrelevant. This is known as "shadowing" the class attribute; you've
re-bound the name to a different object.
def append(self, info):
self.data.append(info)

This defines a function that runs when the 'append' method is called,
and asks the existing object bound to the "data" attribute -- still
the one that was bound when the class was defined -- to modify itself
in-place (with its own 'append' method).
 
T

Tom Plunket

Fredrik said:
if you want separate instances to use separate objects, make sure you
create new objects for each new instance. see Tim's reply for how to
do that.

kath's response is probably better.

In Python, you don't define the instance members in the class scope
like the OP has done:
class A:
name = ""
data = []

You define them when you attach them to an instance, e.g.

class A:
def __init__(self):
self.member1 = 'a'

def ThisWorksToo(self):
self.member2 = 'b'

# this also works
a = A()
a.member3 = 'c'

-tom!
 
F

Fredrik Lundh

Tom said:
kath's response is probably better.

so what's the practical difference between

def __init__(self, name):
self.name = name
self.data = []

and

def __init__(self, name):
self.name = name
self.data=[]

?
> In Python, you don't define the instance members in the class scope
> like the OP has done:

the OP's approach works perfectly fine, as long as you understand that
class attributes are shared.

</F>
 
T

Tom Plunket

Fredrik said:
so what's the practical difference between

def __init__(self, name):
self.name = name
self.data = []

and

def __init__(self, name):
self.name = name
self.data=[]

Ignoring nerd-extreme-pedantic-mode for this circumstance, you elided
the bits that were functionally different.

IOW, based on the OP's post, it appeared that C++ was infecting their
Python, and removing the class attributes entirely was likely what the
OP actually wanted.
the OP's approach works perfectly fine, as long as you understand that
class attributes are shared.

Obviously, as is "sticking a gun in your mouth is perfectly fine, as
long as you understand that pulling the trigger will yield a large
hole in the back of your skull." My reading of the OP's post was that
shared attributes were not desired.

-tom!
 
F

Fredrik Lundh

Tom said:
Obviously, as is "sticking a gun in your mouth is perfectly fine, as
long as you understand that pulling the trigger will yield a large
hole in the back of your skull."

in my experience, the "you're not old enough to understand this"
approach to teaching usually means that the teacher is immature,
not the student. I prefer to explain how things work. everyone
can understand how Python works. it's pretty simple, actually.

</F>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top