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