Python 2.x - References and pointers
Question: I have a question. How can I get "reference-pointer effect" in Python 2.x?

I have a class, containing 2 dictionaries - 1 with character representation
and 1 with integer representation (retrieved with `ord(character)`). Main
problem is I will print them a lot of times, so converting them in-the-fly is
a bad idea (I think). However, switching between them would be useful.

    
    
    class Character_Dict(object):
        def __init__(self, key_length):
            self.char_dict = {}
            self.ASCII_dict = {}
            self.key_length = key_length
            self.dictionary = <<here should be a dictionary in usage>>
    

I could just assign wanted one to `self.dictionary`, but when assigning for
example `self.char_dict` any change in `self.dictionary` would not apply to
`self.char_dict` which in my case is a point of whole this construction.

Is there any mechanism in Python 2.x which would allow to do things like that?

[EDIT 1]: Dictionaries contains lists of symbols encrypted with usage of n-th
byte of some key:

    
    
    n [list of character encrypted with n-th byte of key]
    
    0 ['\xc5', '\x9a', '\xa5', '\x8d', '\xc8', '\xc8', '\x92', '\x9b', '\x82', '\x92', '\x86']
    1 ['a', 'm', '.', 'a', '%', ',', ' ', '*', '$', ' ', '(']
    2 ['\x18', '~', '4', '4', '?', ',', ',', '0', '9', ',', '\xe7']
    3 ['\xe8', '\xe2', '\xe8', '\xec', ':', '\xe6', '\xe6', '0', '\xe6', '\xf3', '\xa9']
    ...
    255 ['\x12', 'S', '\xcc', '_', '\xc0', 'S', '\x01', 'S', 'S', 'S']
    

[EDIT 2]: My encryption key has 256 bytes. Message which was encrypted by
usage of that key is 2688 bytes long. That means that encryption key was
repeated 10.5 times.

Think about changing the 3rd letter which was encrypted with usage of 10th
letter of key. That's (3-1)*256+10 byte. Instead of reading that letter, I can
simply read whole stream and use my class

    
    
    fileXOR = open('2011061.xor', 'r')
    key_length = 256
    
    number_of_bytes = os.path.getsize('2011061.xor')
    print number_of_bytes
    amount_of_key_repetition = number_of_bytes/key_length.__float__()
    print "Key has been repeated", amount_of_key_repetition, "times"
    
    character_dict = Character_Dict(key_length)
    for counter_x in range(0, key_length):
        character_dict.dictionary[counter_x] = []
    print character_dict
    
    for current_byte in range(0, number_of_bytes):
        read_character = fileXOR.read(1)
        character_dict.dictionary[current_byte % key_length].append(read_character)
    
    fileXOR.close()
    

and I can access my character simply by:

    
    
    character_dict.dictionary[10][2]
    

Now, imagine that I need change `character_dict.dictionary[10][2]`. In
constructor I had assigned `self.char_dict` to `self.dictionary`. Changing
`object_name.dictionary` will not modify `object_name.char_dict` (AFAIK).

I want `object_name.dictionary` to be sometimes a ASCII representation, and
sometimes an integer representation. That would reduce a lot of code and
simplify any changes made into ciphertext.


Answer: In Python, the [weakref](https://docs.python.org/2/library/weakref.html)
module lets you store references to objects. If the source object gets deleted
or garbage collected, this can be detected by calling the weakref.

Example from documentation:

    
    
    >>> import weakref
    >>> class Object:
    ...     pass
    ...
    >>> o = Object()
    >>> r = weakref.ref(o)
    >>> o2 = r()
    >>> o is o2
    True
    

If the referent no longer exists, calling the reference object returns None:

    
    
    >>> del o, o2
    >>> print r()
    None
    

