Returning a list/dict as "read-only" from a method ? Prop. not wkg.
Az Tech
aztech1200 at yahoo.com
Fri Jan 3 15:02:10 EST 2003
> > On 26 Dec 2002 05:31:07 -0800, aztech1200 at yahoo.com (Az Tech) wrote:
> >
> > >Hello group,
> > >
> > >Platform: ActivePython 2.2.1 on Windows 98 - but nothing OS-specific
> > >in the code.
> > >This question is about how to return a list/dictionary from a method
> > >(of a class) in such a way that it stays "read-only" to the caller -
> > >or any other technique that is equivalent in terms of effect. Read on
>
Hi people,
Some had suggested using the new 'property' feature of Py 2.2 to solve
this problem.
I tried it out, but it does not work unless I do a copy of the self.list
or self.dict before returning it.
Sample code and output below.
# New_2.2_deep_copy_nested_list01.py
# Program to test deep copy of nested list.
class BinaryFile(object):
import copy
def __init__(self):
pass
def make_list2(self):
self.__a_list2 = [ [1, 2], [3, 4], [5, 6] ]
def get_list2(self):
t_list2 = copy.deepcopy(self.__a_list2)
return t_list2
# set_list2() not defined
# del_list2() not defined
list2 = property(get_list2, None,
None,
"Two-level nested list")
def main():
bf = BinaryFile()
bf.make_list2()
#print "bf.get_list2() = ", bf.get_list2() #1
print "bef mod, bf.list2 = ", bf.list2 #2
#bf.list2 = [] #3
bf.__a_list2 = [ [0], [1] ]
print "aft mod, bf.list2 = ", bf.list2 #4
print "bf.__a_list2 = ", bf.__a_list2
if __name__ == '__main__':
main()
Output:
>>> bef mod, bf.list2 =
>>> [[1, 2], [3, 4], [5, 6]]
>>> aft mod, bf.list2 =
>>> [[1, 2], [3, 4], [5, 6]]
>>> bf.__a_list2 =
>>> [[0], [1]]
>>>
[Note: the last two lines of the output above show that it is still
possible, though, to assign to the instance's __a_list2 member - even
though this does not affect the value of the property. Is this some kind
of 'shadowing' of the member variable ?
(Used the same printing of id() both in the method and in the caller,
and it returned the same value. )
Was able to modify the member variable using the return value of the
method. The only way in which I could prevent it from being modified
was by making my self.list or self.dict as 'private', using a leading
double underscore, e.g. self.__list, as in the code above.
Also, I can get the desired result without using property at all,
simply by doing a copy (or a copy.deepcopy()) of the list/dict.
I've finally settled on this approach:
import copy
.
.
.
then, in the method, do hand-coded copy if the element is a 'scalar'
variable (a la Perl), else, if a list/dict, do a copy.deepcopy(list/dict)
and then return that copy.
Just FYI.
Az
More information about the Python-list
mailing list