Mailing List Archive

Python's object model
Hello,

I'm new at Python. In the following program, "stack_1 pops stack_2's
content" (that's actually what it prints), which is obviously not what
I'm after - nor would expect. Is this how Python's object model really
works (kindly explain), is there some arcane rule that I've missed, or
is there some obvious mistake I just can't see?

Aside from a few such quirks, it's quite an interesting language (I'm
using 1.5.1 - on both Linux and NT).

Thanks,

Francois

-------------------------------------

class Stack:
stack = []

def push(self, value):
self.stack.append(value)

def pop(self):
result = self.stack[-1]
del self.stack[-1]
return result

class System:
stack_1 = Stack()
stack_2 = Stack()

def __init__(self):
self.stack_1.push('stack_1\'s content')
self.stack_2.push('stack_2\'s content')
print 'stack_1 pops', self.stack_1.pop()

# 'main'

system = System()
Python's object model [ In reply to ]
This "Stack" class:


class Stack:
stack = []

def push(self, value):
self.stack.append(value)

...

doesn't work as you expected because the way you've declared it, the
".stack" attribute is a class attribute (shared by all instances of
the class) rather than an instance attribute. To create instance
attriubtes, create them in the initializer, like this:

class Stack:
def __init__(self):
self.stack = ()

def push(self, value):
...

Also note that in the not-quite-yet released Python 1.5.2 the builtin
list objects have a pop() method, which is kind of handy.
Python's object model [ In reply to ]
Francois Bedard wrote:

> Hello,
>
> I'm new at Python. In the following program, "stack_1 pops stack_2's
> content" (that's actually what it prints), which is obviously not what
> I'm after - nor would expect. Is this how Python's object model really
> works (kindly explain), is there some arcane rule that I've missed, or
> is there some obvious mistake I just can't see?
>
> Aside from a few such quirks, it's quite an interesting language (I'm
> using 1.5.1 - on both Linux and NT).
>
> Thanks,
>
> Francois
>
> -------------------------------------
>
> class Stack:
> stack = []
>
> def push(self, value):
> self.stack.append(value)
>
> def pop(self):
> result = self.stack[-1]
> del self.stack[-1]
> return result
>
> class System:
> stack_1 = Stack()
> stack_2 = Stack()
>
> def __init__(self):
> self.stack_1.push('stack_1\'s content')
> self.stack_2.push('stack_2\'s content')
> print 'stack_1 pops', self.stack_1.pop()
>
> # 'main'
>
> system = System()

Hi Francois

what you're seeing is the difference between a class and an
instance variable. To see the behaviour you want you need to
modify your stack class as follows:

class Stack:
def __init__(self):
self.stack = []

def push(self, value):
self.stack.append(value)

def pop(self):
result = self.stack[-1]
del self.stack[-1]
return result

Otherwise the stack is a class variable which can be referred as
Stack.stack() (this would then act as a class global).

Cheers
Florent Heyworth
Python's object model [ In reply to ]
Thank you both, Charles and Florent. I'm most familiar with Eiffel's
object model and apparently generalized a bit hastily, but your answers
did clarify things...

Francois

Francois Bedard wrote :
>
> I'm new at Python. In the following program, "stack_1 pops stack_2's
> content" (that's actually what it prints), which is obviously not what
> I'm after - nor would expect. [...]
>
> class Stack:
> stack = []
> [...]
>
> class System:
> stack_1 = Stack()
> stack_2 = Stack()
> [...]

Charles G Waldman wrote :
>
> This "Stack" class [...]
> doesn't work as you expected because the way you've declared it, the
> ".stack" attribute is a class attribute (shared by all instances of
> the class) rather than an instance attribute. To create instance
> attriubtes, create them in the initializer, like this:
>
> class Stack:
> def __init__(self):
> self.stack = ()
> [...]

Florent Heyworth wrote :
>
> what you're seeing is the difference between a class and an
> instance variable. To see the behaviour you want you need to
> modify your stack class as follows:
>
> class Stack:
> def __init__(self):
> self.stack = []
> [...]
>
> Otherwise the stack is a class variable which can be referred as
> Stack.stack() (this would then act as a class global).
> [...]