[portland] __gitattrib__ idoms. How often are they used?

Christopher Hiller chiller at decipherinc.com
Mon Jan 27 04:43:43 CET 2014


Here are a few use cases, some more useful than others.

class Baz(object):
    """
    I namespace my variables because reasons.
    """

    baz_sheep = 'mutton'
    baz_cow = 'beef'
    baz_pig = 'pork'

    def __getattr__(self, name):
        return getattr(self, 'baz_%s' % name)


baz = Baz()
print baz.cow  # 'beef'


class Foo(dict):
    """
    I am some sort of struct-like object.

    Usefulness becomes more obvious when nested deeply:

    (dict) one['two']['three']['four']['five']['six']
    (Foo) one.two.three.four.five.six

    ..but you can use me either way.
    """

    def __getattr__(self, name):
        try:
            return self[name]
        except KeyError:
            raise AttributeError(name)

    def __setattr__(self, name, value):
        self[name] = value

    def __delattr__(self, name):
        del self[name]


foo = Foo(herp='derp',
          hash=dict(frick='frack'),
          array=['tweedledee', 'tweedledum'])
print foo.herp  # 'derp'


class Bar(Foo):
    """
    I'm an encoded struct?

    I suppose this is marginally interesting.
    """

    def __init__(self, codec, d=None, **kwargs):
        """
        :type codec: str
        """
        from codecs import lookup

        self.__dict__['__codec__'] = lookup(codec)
        for k, v in dict(d or dict(), **kwargs).items():
            setattr(self, k, v)

    @property
    def __codec__(self):
        return self.__dict__['__codec__']

    def __getattr__(self, name):
        return self.__codec__.decode(super(Bar, self).__getattr__(name))[0]

    def __setattr__(self, name, value):
        super(Bar, self).__setattr__(name, self.__codec__.encode(value)[0])


bar = Bar('rot13', beavis='butthead')
print bar.beavis  # 'butthead'
print bar['beavis']  # 'ohggurnq'
print bar.__codec__  # <codecs.CodecInfo object for encoding rot-13 at ...>
bar.__codec__ = 'foo'
print bar.__codec__  # <codecs.CodecInfo object for encoding rot-13 at ...>
print bar['__codec__']  # 'sbb'
bar['daria'] = 'morgendorffer'
print bar.daria  # 'zbetraqbessre' (oops; it wasn't encoded in the first place!)
The bar.__codec__ = 'foo' is especially weird; it doesn't raise an exception but feels like it should. Couldn't figure out how to get that to happen; tried both:

@property
def __codec__(self, value=None):
    if value is not None:
        raise ValueError()
    return self.__dict__['__codec__']
and

@__codec__.setter
def __codec__(self, value):
    raise ValueError()
...but neither was triggered with a bar.__codec__ = 'foo'. Anyone know what's up with that?

Chris

 
-- 
Christopher Hiller
Decipher, Inc.

On January 26, 2014 at 3:36:34 PM, Ethan Furman (ethan at stoneleaf.us) wrote:

On 01/26/2014 02:04 PM, mark gross wrote:  
> On Sun, Jan 26, 2014 at 12:16:37PM -0800, Ethan Furman wrote:  
>> On 01/26/2014 12:06 PM, mark gross wrote:  
>>>  
>>> But, I'd like to ask the pdx-python crew about uses of __getattrib__.  
>>  
>> There is no __getattrib__ -- there is a __getattr__ and a __getattribute__; which did you mean?  
>  
> Sorry for the type-oh. I'm talking about __getattr__  

Okay, I read your blog entry -- pretty nice!  

And yes, __getattr__ is at the tail-end of lookup attempts that Python will perform when trying to find an attribute on  
an object, and yes, you can do juts about anything there. The only thing more powerful than __getattr__ is  
__getattribute__ (because __getattribute__ is *always* called, while __getattr__ is only called when an attribute cannot  
be found).  

The most common use for __getattr__ is to allow virtual attributes, and the way git-python is using it is normal.  

Because __getattr__ can be a bit of a nuisance for introspection other helper-type methods have been added, such as  
__dir__ (so git-python could specify in its __dir__ method the various command-line converters it allowed); also,  
descriptors (such as property) are encouraged where appropriate.  

--  
~Ethan~  
_______________________________________________  
Portland mailing list  
Portland at python.org  
https://mail.python.org/mailman/listinfo/portland  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/portland/attachments/20140126/a5a30a17/attachment.html>


More information about the Portland mailing list