473,405 Members | 2,444 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Data sticking around too long

Greetings!

Here's my script:

######## start of script
class ScannerCommand:
taskName = ''
scanList = []

def __init__(self):
print "Creating a ScannerCommand object; list has " + \
str(len(self.scanList)) + " objects."

class Scanner:
def Read(self, data):
command = ScannerCommand()
command.scanList.append(data)
return command

class Handler:
def Process(self, dataList):
print "Processing data"
for data in dataList:
print " " + data
print "Finished processing data."

if __name__ == '__main__':
s = Scanner()
count = 0
for data in ["Zero", "One", "Two", "Three"]:
command = s.Read(data)
handler = Handler()
handler.Process(command.scanList)
############## End of script

Here's the result:

########## Start of result
Processing data
Zero
Finished processing data.
Creating a ScannerCommand object; list has 1 objects.
Processing data
Zero
One
Finished processing data.
Creating a ScannerCommand object; list has 2 objects.
Processing data
Zero
One
Two
Finished processing data.
Creating a ScannerCommand object; list has 3 objects.
Processing data
Zero
One
Two
Three
Finished processing data.
################ End of result

I had expected to get "Zero" by itself, then "One" by itself, and so
on.

Why is the ScannerCommand object being created with a scanList that
contains the data that was in the previously created ScannerCommand
object? And what do I have to do to ensure that the code that is run
when I call ScannerCommand() gives me an object with an empty scanList?

I am a C++ developer in a shop that uses some Python as well, and I
just ran across this behavior for the first time. I believe it is due
to the difference between binding a variable to an object, as Python
does, and actually creating the variable, as a similar C++ application
would do.

Thank you very much.

Rob Richardson
RAD-CON, Inc.
Bay Village, OH

Sep 6 '06 #1
8 1229

CedricWhy is the ScannerCommand object being created with a scanList
Cedricthat contains the data that was in the previously created
CedricScannerCommand object?

Your scanList attribute is defined at the class level and is thus shared by
all ScannerCommand instances.

Skip
Sep 6 '06 #2
taskName and scanList are defined at the class level making them class
attributes. Each instance of the ScannerCommand class will share its
class attributes. What you want are instance attributes which can be
initialized whithin the constructor like so:
>>class ScannerCommand:
.... def __init__(self):
.... self.taskName = ''
.... self.scanList = []
.... print "Creating a ScannerCommand object; list has " + \
.... str(len(self.scanList)) + " objects."
Ce**********@gmail.com wrote:
Greetings!

Here's my script:

######## start of script
class ScannerCommand:
taskName = ''
scanList = []

def __init__(self):
print "Creating a ScannerCommand object; list has " + \
str(len(self.scanList)) + " objects."

class Scanner:
def Read(self, data):
command = ScannerCommand()
command.scanList.append(data)
return command

class Handler:
def Process(self, dataList):
print "Processing data"
for data in dataList:
print " " + data
print "Finished processing data."

if __name__ == '__main__':
s = Scanner()
count = 0
for data in ["Zero", "One", "Two", "Three"]:
command = s.Read(data)
handler = Handler()
handler.Process(command.scanList)
############## End of script

Here's the result:

########## Start of result
Processing data
Zero
Finished processing data.
Creating a ScannerCommand object; list has 1 objects.
Processing data
Zero
One
Finished processing data.
Creating a ScannerCommand object; list has 2 objects.
Processing data
Zero
One
Two
Finished processing data.
Creating a ScannerCommand object; list has 3 objects.
Processing data
Zero
One
Two
Three
Finished processing data.
################ End of result

I had expected to get "Zero" by itself, then "One" by itself, and so
on.

Why is the ScannerCommand object being created with a scanList that
contains the data that was in the previously created ScannerCommand
object? And what do I have to do to ensure that the code that is run
when I call ScannerCommand() gives me an object with an empty scanList?

I am a C++ developer in a shop that uses some Python as well, and I
just ran across this behavior for the first time. I believe it is due
to the difference between binding a variable to an object, as Python
does, and actually creating the variable, as a similar C++ application
would do.

Thank you very much.

Rob Richardson
RAD-CON, Inc.
Bay Village, OH
Sep 6 '06 #3
Skip and Matimus,

Thank you for your replies. Putting initialization in the constructor
gets me what I want. But I'd like to understand this a bit more.
Here's another script:

class ScannerCommand:
taskName = ''
scanList = []

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

if __name__ == '__main__':
c1 = ScannerCommand("c1")
c2 = ScannerCommand("c2")
print "C1: "
for data in c1.scanList:
print " " + data
print "C2: "
for data in c2.scanList:
print " " + data

And here's the output, which is what I want:
C1:
c1
C2:
c2

If scanList is a class variable shared between all instances of the
class, then C1's list should have held "C2" when I printed it, since C2
came along and changed scanList. But obviously, here it's not a class
variable and the two instances have their own lists.

If I don't initialize scanList in the constructor, then scanList is a
class variable (in C++, it would be a static member of the class) that
is shared among all instances of the class. If I do initialize
scanList in the constructor, then scanList magically becomes an
instance variable, with every instance of the ScannerCommand object
having its own scanList list??? Is that really the way it works? I
would have thought the C++ way, with some special syntax to distinguish
a class variable from an instance variable, would be much easier to
work with.

Thanks again!

Rob Richardson
RAD-CON, Inc.
Bay Village, OH

Sep 6 '06 #4
Ce**********@gmail.com wrote:
Skip and Matimus,

Thank you for your replies. Putting initialization in the constructor
gets me what I want. But I'd like to understand this a bit more.
Here's another script:

class ScannerCommand:
taskName = ''
scanList = []

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

if __name__ == '__main__':
c1 = ScannerCommand("c1")
c2 = ScannerCommand("c2")
print "C1: "
for data in c1.scanList:
print " " + data
print "C2: "
for data in c2.scanList:
print " " + data

And here's the output, which is what I want:
C1:
c1
C2:
c2

If scanList is a class variable shared between all instances of the
class, then C1's list should have held "C2" when I printed it, since C2
came along and changed scanList. But obviously, here it's not a class
variable and the two instances have their own lists.

If I don't initialize scanList in the constructor, then scanList is a
class variable (in C++, it would be a static member of the class) that
is shared among all instances of the class. If I do initialize
scanList in the constructor, then scanList magically becomes an
instance variable, with every instance of the ScannerCommand object
having its own scanList list??? Is that really the way it works? I
would have thought the C++ way, with some special syntax to distinguish
a class variable from an instance variable, would be much easier to
work with.

Thanks again!

Rob Richardson
RAD-CON, Inc.
Bay Village, OH
You shadowed the class attribute scanList by creating an instance
variable called self.scanList in the __init__ method:

self.scanList = []

Comment that line out and see what you get.

-Larry Bates
Sep 6 '06 #5
Greetings again!

There's something more to determining whether a class member is a class
variable or an instance variable. Here's a slightly expanded version
of my last script:

class ScannerCommand:
taskName = ''
scanList = []
number = 0

def __init__(self, data):
pass
# self.scanList = []
# self.scanList.append(data)

if __name__ == '__main__':
c1 = ScannerCommand("c1")
c2 = ScannerCommand("c2")
c1.number = 1
c2.number = 2
c1.scanList.append("One")
c2.scanList.append("Two")
print "C1: " + str(c1.number)
for data in c1.scanList:
print " " + data
print "C2: " + str(c2.number)
for data in c2.scanList:
print " " + data

And here's the output:
C1: 1
One
Two
C2: 2
One
Two

Here, the two instances share the scanList list, as expected from
previous discussions, but they have their own copies of the number
variable. Why is scanList a class variable but number an instance
variable here?

Good night, all!

Rob Richardson
RAD-CON, Inc.
Bay Village, OH

Sep 6 '06 #6
CedricBut I'd like to understand this a bit more.

Always a good idea. ;-)

CedricHere's another script:

Cedricclass ScannerCommand:
Cedric taskName = ''
Cedric scanList = []

Cedric def __init__(self, data):
Cedric self.scanList = []
Cedric self.scanList.append(data)
...

The assignment to self.scanList in __init__ creates an instance attribute in
the ScannerCommand instance. The scanList attribute at the class level is
available as ScannerCommand.scanList. In your previous code, (no assignment
to self.scanList in __init__), references to self.scanList would search
first in the instance dict for a "scanList" key, then failing to find
anything there, search the class's dict and find its "scanList" key.

Skip
Sep 6 '06 #7
Someone correct me if I'm wrong (sometimes I get the terms mixed up)
but I believe that what you are seeing is due to 'number' being an
immutable type. This means that its value cannot be changed and thus
each assignment is effectively creating a new instance if int. I
believe lists are considered immutable also but since it is a container
type it behaves somewhat differently. I read a thread earlier that
addressed a similar issue but I can't find it now. I will post again if
I come accross it. Anyway, as a demonstration try this using python's
command line prompt:
>>i = int()
j = i
j is i
True
### j and i are attributes that point to the same instance
>>i = 1
j is i
False
### assignment to I made a new instance and j and i are no longer the
same instance
>>a = [0,1,2]
b = a
b is a
True
### the same is true for lists
>>b = [0,1,3]
b is a
False
>>b = a
b is a
True
### but since 'a' is a container its contents can be modified without
creating a new instance
>>b[1] = 3
b is a
True
>>a
[0,3,2]
>>b
[0,3,2]
>>a.append(4)
a
[0,3,2,4]
>>b
[0,3,2,4]
>>b is a
True

I hope this helps.

-Matt

Ce**********@gmail.com wrote:
Greetings again!

There's something more to determining whether a class member is a class
variable or an instance variable. Here's a slightly expanded version
of my last script:

class ScannerCommand:
taskName = ''
scanList = []
number = 0

def __init__(self, data):
pass
# self.scanList = []
# self.scanList.append(data)

if __name__ == '__main__':
c1 = ScannerCommand("c1")
c2 = ScannerCommand("c2")
c1.number = 1
c2.number = 2
c1.scanList.append("One")
c2.scanList.append("Two")
print "C1: " + str(c1.number)
for data in c1.scanList:
print " " + data
print "C2: " + str(c2.number)
for data in c2.scanList:
print " " + data

And here's the output:
C1: 1
One
Two
C2: 2
One
Two

Here, the two instances share the scanList list, as expected from
previous discussions, but they have their own copies of the number
variable. Why is scanList a class variable but number an instance
variable here?

Good night, all!

Rob Richardson
RAD-CON, Inc.
Bay Village, OH
Sep 6 '06 #8
Hello Matimus,

On 2006-09-07 00:07, Matimus wrote:
Someone correct me if I'm wrong (sometimes I get the terms mixed up)
but I believe that what you are seeing is due to 'number' being an
immutable type. This means that its value cannot be changed and thus
each assignment is effectively creating a new instance if int.
The significant difference is not between mutable and immutable
objects, but between modifying an object in-place
(e. g. some_list.append(1)) and assigning an object to a name
(e. g. some_int = 1). If you do an assignment to a class
"variable", the binding to the previous object (if any) will be
removed and a new binding to the assigned object created.

The assignments Rob does with

c1.number = 1
c2.number = 2

create a new name "number" in each of the instances' namespaces
and assign the objects 1 and 2 to them, respectively. In contrast,
the list scanList is modified in-place with

c1.scanList.append("One")
c2.scanList.append("Two")

so no names are created in the instances' namespaces and both
operations modify the object in the class's namespace.
I believe lists are considered immutable also
I guess you confuse this with tuples.
but since it is a container
type it behaves somewhat differently.
Again, this has nothing per se to do with being a container
though many containers are mutable objects and often are
modified in-place.

Stefan
Sep 7 '06 #9

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

Similar topics

12
by: Jerry Weinstein | last post by:
Hi, I know about stored procedures and that they can speed up data entry via the SQL 'insert ' statement. However, one drawback to this method is that using the stored procedure still requires...
5
by: Simon Harvey | last post by:
Hi everyone, I'm hoping for a little bit of advice on the following. I am in the process of making a small application that can send, receive and store email messages. The current area that I am...
3
by: Simon Harvey | last post by:
Hi, In my application I get lots of different sorts of information from databases. As such, a lot of information is stored in DataSets and DataTable objects. Up until now, I have been passing...
5
by: Mike | last post by:
Hi, I'm new to vb.net and would be grateful if anyone could offer some advice on the best way to approach this problem: I wish to dynamically capture pricing information e.g. 10 stock prices...
18
by: Vayse | last post by:
Has anyone an example of filling a combo box with a data reader? Thanks Vayse
3
by: pemigh | last post by:
A while back I imported tables to a new database via Files-->Get External Data --> Import... All was well for several months, and then the database started behaving badly in a couple of ways,...
1
by: jrs_14618 | last post by:
Hello All, This post is essentially a reply a previous post/thread here on this mailing.database.myodbc group titled: MySQL 4.0, FULL-TEXT Indexing and Search Arabic Data, Unicode I was...
22
by: Zytan | last post by:
I have public methods in a form. The main form calls them, to update that form's display. This form is like a real-time view of data that is changing. But, the form may not exist (it is...
15
by: sara | last post by:
I have a Memo field in a table to hold notes from a conversation a social worker has had with a client (this is for a non-profit). If the user needs to update the memo field, I need to find the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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...
0
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...

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.