File: prototype.py

package info (click to toggle)
egenix-mx-base 3.2.8-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 8,420 kB
  • ctags: 6,208
  • sloc: ansic: 22,304; python: 18,124; sh: 137; makefile: 121
file content (138 lines) | stat: -rw-r--r-- 3,621 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
""" Proxy prototype written in Python. The C version is a little different,
    but this should give a general idea of how the type works.

    Copyright (c) 2000, Marc-Andre Lemburg; mailto:mal@lemburg.com
    Copyright (c) 2000-2014, eGenix.com Software GmbH; mailto:info@egenix.com
    See the documentation for further information on copyrights,
    or contact the author. All Rights Reserved.
"""

import types

class Proxy:

    def __init__(self,object,interface=None):

        # All these private attributes will be hidden in the C
        # implementation
        self.__object = object

        if interface:
            d = {}
            for item in interface:
                if type(item) == types.StringType:
                    d[item] = 1
                else:
                    d[item.__name__] = 1
            self.__interface = d
        else:
            self.__interface = None

        if hasattr(object,'__public_getattr__'):
            self.__public_getattr = object.__public_getattr__
        else:
            self.__public_getattr = None

        if hasattr(object,'__public_setattr__'):
            self.__public_setattr = object.__public_setattr__
        else:
            self.__public_setattr = None

        if hasattr(object,'__cleanup__'):
            self.__cleanup = object.__cleanup__
        else:
            self.__cleanup = None

    def __getattr__(self,what):

        if self.__interface and not self.__interface.has_key(what):
            raise AttributeError,'attribute access restricted'
        if self.__public_getattr:
            return self.__public_getattr(what)
        else:
            return getattr(self.__object,what)

    def __setattr__(self,attr,obj):

        if attr[:8] == '_Proxy__':
            self.__dict__[attr] = obj
            return
        if self.__interface and not self.__interface.has_key(attr):
            raise AttributeError,'attribute access restricted'
        if self.__public_setattr:
            self.__public_setattr(attr,obj)
        else:
            return setattr(self.__object,attr,obj)

    def __del__(self):

        if self.__cleanup:
            self.__cleanup()

class ProxyFactory:

    def __init__(self,Class,interface=()):

        self.Class = Class
        self.interface = interface

    def __call__(self,*args,**kw):

        """ Return a new object 
        """
        return Proxy(apply(self.Class,args,kw),self.interface)

    def __repr__(self):

        return '<ProxyFactory for %s>' % repr(self.Class)

class A:

    a = 1
    b = 2

    def __init__(self):

        self.c = 3

    def __public_getattr__(self,what):

        """ If given, this method is called for all public getattr access
            to the object.
        """
        print 'public getattr',what
        return getattr(self,what)
        
    def __public_setattr__(self,what,to):

        """ If given, this method is called for all public setattr access
            to the object.
        """
        print 'public setattr',what,'to',to
        return setattr(self,what,to)
        
    def write(self,value):
        
        self.a = value

    def read(self):

        return self.a

    def __str__(self):

        return str(self.a)

    def __cleanup__(self):

        """ If given, this method is called if the proxy object gets
            garbage collected. You can use it to break circular references
            the object might have introduced.
        """
        print 'cleanup'
        self.__dict__.clear()

AA = ProxyFactory(A,(A.read,A.write,'__str__'))

o = Proxy(A(),(A.read,A.write,'__str__'))
p = AA()