Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I've coded my own proxy class in python. The aim is to have a different type() but otherwise behave as identical to the underlying object as possible. I'm wondering if there's any problems with it or any use cases where it won't work.

Something strange I've noticed is that Proxy(1).__class__ is int, which isn't very desirable, but I'm unsure why this occurs.

I got some inspiration from this recipe, and the examples behave in the same way.

class Proxy:
    def __new__(cls, obj, *args, **kwargs):
        '''
        Creates a proxy instance referencing obj.

        _proxy_class_cache is unique per deriving class (each deriving class must hold its own cache).
        '''
        try:
            cache = cls.__dict__['_proxy_class_cache']
        except KeyError:
            cls._proxy_class_cache = cache = {}
        try:
            src_class = cache[type(obj)]
        except KeyError:
            cache[type(obj)] = src_class = cls._create_proxy_class(type(obj))
        return object.__new__(src_class)

    def __init__(self, obj):
        object.__setattr__(self, '_obj', obj)

    def __getattribute__(self, name):
        return getattr(object.__getattribute__(self, '_obj'), name)

    @classmethod
    def _create_proxy_class(cls, src_class):
        '''
        Creates a proxy class for the source class.
        '''
        def wrap_method(name_):
            def wrapper(self, *args, **kw):
                return getattr(object.__getattribute__(self, '_obj'), name_)(*args, **kw)
            return wrapper

        namespace = {}
        for name, prop in src_class.__dict__.items():
            if name == '__init__':
                continue
            if callable(prop):
                namespace[name] = wrap_method(name)
            else:
                namespace[name] = prop
        return type('{}_{}'.format(cls.__name__, src_class.__name__), (cls,) + src_class.__bases__, namespace)
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.