Agent property access

Attribute access agent commonly used as an alternative class inheritance easiest access code Agent properties as follows:

class A:
    def spam(self, x):
        pass

    def foo(self):
        pass


class B:
    def __init__(self):
        self._a = A()

    def spam(self, x):
        # Delegate to the internal self._a instance
        return self._a.spam(x)

    def foo(self):
        # Delegate to the internal self._a instance
        return self._a.foo()

    def bar(self):
        pass

If the method requires only a few agents, __getattr__ class methods can be implemented as follows:

class A:
    def spam(self, x):
        pass

    def foo(self):
        pass


class B:
    def __init__(self):
        self._a = A()

    def bar(self):
        pass

    # Expose all of the methods defined on class A
    def __getattr__(self, name):
        return getattr(self._a, name)

>>> b = B()
>>> b.bar()
>>> b.spam(42)

Another example:

class Proxy:
    def __init__(self, obj):
        self._obj = obj

    # Delegate attribute lookup to internal obj
    def __getattr__(self, name):
        print('getattr', name)
        return getattr(self._obj, name)

    # Delegate attribute assignment
    def __setattr__(self, name, value):
        if name.startswith('_'):
            super().__setattr__(name, value)
        else:
            print('setattr:', name, value)
            setattr(self._obj, name, value)

    # Delegate attribute deletion
    def __delattr__(self, name):
        if name.startswith('_'):
            super().__delattr__(name)
        else:
            print('delattr:', name)
            delattr(self._obj, name)


class Spam:
    def __init__(self, x):
        self.x = x
    def bar(self, y):
        print('Spam.bar:', self.x, y)


>>> s = Spam(2)
>>> p = Proxy(s)
>>> print(p.x)
getattr x
2
>>> p.bar(3)
getattr bar
Spam.bar: 2 3
>>> p.x = 37
setattr: x 37

Common convention is that the agent can not be delegated to attribute the leading underscore (that is, the proxy exposes only the reserved instance of "public" property).
It is also important to emphasize __getattr __ () method is usually not suitable for most special way to the beginning and end of a double underline. as follows:

class ListLike:
    def __init__(self):
        self._items = []
    
    def __getattr__(self, name):
        return getattr(self._items, name)


>>> a = ListLike()
>>> a.append(2)
>>> a.insert(0, 1)
>>> a.sort()
>>> len(a)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: object of type 'ListLike' has no len() 
>>> a[0]
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: 'ListLike' object does not support indexing 
>>>

To achieve such len, indexing method, you must implement as __len __, __ getitem __, __ setitem __, __ delitem__ other methods.

Guess you like

Origin www.cnblogs.com/jeffrey-yang/p/12142481.html