Note
There are a number of classes and meta-classes but the only public interface is the proxy class. See below for examples.
A mostly transparent proxy type
The proxy class can be used in two different ways. First, as a callable proxy(obj). This simply returns a proxy for a single object.
>>> truth = ['trust no one']
>>> lie = proxy(truth)
This will return an instance of a new proxy sub-class which for all intents and purposes, to the extent possible in CPython, forwards all requests to the original object.
One can still examine the proxy with some ways:
>>> lie is truth
False
>>> type(lie) is type(truth)
False
Having said that, the vast majority of stuff will make the proxy behave identically to the original object.
>>> lie[0]
'trust no one'
>>> lie[0] = 'trust the government'
>>> truth[0]
'trust the government'
The second way of using the proxy class is as a base class. In this way, one can actually override certain methods. To ensure that all the dunder methods work correctly please use the @unproxied decorator on them.
>>> import codecs
>>> class crypto(proxy):
...
... @unproxied
... def __repr__(self):
... return codecs.encode(super().__repr__(), "rot_13")
With this weird class, we can change the repr() of any object we want to be ROT-13 encoded. Let’s see:
>>> orig = ['ala ma kota', 'a kot ma ale']
>>> prox = crypto(orig)
We can sill access all of the data through the proxy:
>>> prox[0]
'ala ma kota'
But the whole repr() is now a bit different than usual:
>>> prox
['nyn zn xbgn', 'n xbg zn nyr']