Need to pass Object by value into a list
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Mon Sep 26 16:41:26 EDT 2005
Aaron a écrit :
> I have a data sructure setup and I populate it in a loop like so:
>
> y=0
> while X:
> DS.name = "ASDF"
> DS.ID = 1234
> list[y] = DS;
> y = y + 1
>
> print list
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/tmp/python-9150sSF", line 2, in ?
while X:
NameError: name 'X' is not defined
Please post running code. The rule is:
- explain what you did
- explain what you expected
- explain what you've got
- post the minimal running code that reproduce the problem
Here are a short listing of errors and bad style in this code:
1/ DS is not defined
2/ X is not defined
3/ 'list' is the name of the builtin class list. The list *class* is
unsubscriptable.
4/ Assuming you rebound the name 'list' to a list instance (which is a
very Bad Thing(tm)), you still can't assign to an inexistant index
5/ even if DS and X were defined, this loop would run forever
6/ In Python, identifiers in uppercase are constants (well... this is
only a convention, but convention in Python are part of the language,
even if there's nothing to enforce them)
7/ you mix arbitrary naming conventions ('DS.name' vs 'DS.ID', 'X' vs 'y').
Either this is not your real code or you did not try to run this code.
In fact, I guess this is not your real code AND you did not try to run
it. Please do *yourself* a favor: post running code (I don't mean 'code
that don't crash', I mean: 'code that reproduce your real problem').
> This does not work
"Does not work" is the worst possible description of a problem.
Now effectively, this code (the one you posted, not the one you are
describing) crashes for a very obvious reason (see point n°1 above). The
code you are describing (which is obviously different...) "works" - it
may not behave how you'd expect it to, but this is another problem.
> because DS is passed in by reference causing all
> entries into the list to change to the most current value.
DS is not 'passed by reference', since there is no function call in your
code. A reference to the object bound to the name DS is stored (well, I
assume this is what happen in your real code) in the list - which is
not the same thing.
<digression>
BTW, you need to understand that, in Python, an identifier is just a
name bound to a reference to an object. Think of the namespace as a
hashtable with names as keys and references to objects as values (this
exactly how it's implemented). When it comes to function calls, the
*name* is local to the function, but the object referenced by the name
is the original object. If you rebind the name (ie: 'assign' another
object to it), this change will be local, because the *name* is local.
But if you modify the object itself, this will impact the 'original'
object, ie:
def fun(aList, anotherList):
# rebind local name 'aList', original object not impacted
aList = [1, 2, 3]
# modify ('mutate') object bound to 'anotherList',
# original object impacted
anotherList.append(42)
listOne = [4, 5, 6]
listTwo = [7, 8, 9]
fun(listOne, listTow)
print listOne
print listTwo
</digression>
> I cannot
> find a "new" function in Python like there is in C++.
<pedantic>
In C++, 'new' is an operator, not a function.
</pedantic>
In Python, classes are callable objects (a callable is something like a
function - or, should I say, a function is a kind of callable object -
everything in Python being an object...) that return an instance when
called. So there is no need for a 'new' operator - just call the class
object (like you'd call a function), and you'll get an instance. Also,
if the class has an '__init__' method, this method will be called after
object instanciation, with the arguments passed when calling the class.
ie:
class Foo(object):
def __init__(self, name):
self.name = name
f = Foo('foo')
f.name
=> 'foo'
> How do you do
> this in Python?
>
class Ds(object):
def __init__(self, id, name):
self.id = id
self.name = name
x = 42 # or any other integer value
# short way
ds_list = [Ds(1234, "ASDF") for i in range(x)]
print ds_list
# verbose way:
ds=list = []
for i in range(x):
ds_list.append(Ds(1234, "ASDF")
print ds_list
ds_list[0].name="FOO"
print ds_list
HTH
More information about the Python-list
mailing list