__getattribute__ and __slots__

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pascal.parent@free.fr

    #1

    __getattribute__ and __slots__

    Hi,
    I try to define a (new-style) class who:
    - have a __slots__ defined to be strict attributes,
    - return None if the attribute is 'ok' but not set, or raise a 'normal'
    error if the attribute isn't in __slots__.

    This code runs, but is it the good way?

    Thanks.

    class test(object):
    __slots__ = ['id']
    def __getattr__(sel f, attr):
    if not attr in self.__slots__: raise AttributeError
    try:
    return self.attr
    except:
    return None

  • Peter Otten

    #2
    Re: __getattribute_ _ and __slots__

    pascal.parent@f ree.fr wrote:

    Python has both __getattribute_ _() and __getattr__(). While
    __getattribute_ _() will always be called if you ask for an attribute
    __getattr__() serves only as fallback if the attribute if not found by
    other means.
    [color=blue]
    > I try to define a (new-style) class who:
    > - have a __slots__ defined to be strict attributes,[/color]

    __slots__ is a performance/memory optimization. Using __slots__ to introduce
    bondage & discipline through the backdoor is against Python's spirit.
    [color=blue]
    > - return None if the attribute is 'ok' but not set, or raise a 'normal'
    > error if the attribute isn't in __slots__.[/color]

    The approach you have chosen is a very ineffective one. Why don't you just
    set the attribute to a default value in the initializer?
    [color=blue]
    > This code runs, but is it the good way?[/color]

    I don't think so...
    [color=blue]
    > class test(object):
    > __slots__ = ['id']
    > def __getattr__(sel f, attr):
    > if not attr in self.__slots__: raise AttributeError
    > try:
    > return self.attr[/color]

    The line above does not do what you think it does. It just calls
    test_instance._ _getattr__("att r"), and since "attr" is not in __slots__ it
    raises an AttributeError.
    [color=blue]
    > except:
    > return None[/color]

    You should get the same effect with
    [color=blue][color=green][color=darkred]
    >>> class T(object):[/color][/color][/color]
    .... __slots__ = ["id"]
    .... def __getattr__(sel f, name):
    .... if name not in self.__slots__:
    .... raise AttributeError
    .... return 42 # for better visibility
    ....[color=blue][color=green][color=darkred]
    >>> t = T()
    >>> t.id[/color][/color][/color]
    42[color=blue][color=green][color=darkred]
    >>> t.whatever[/color][/color][/color]
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    File "<stdin>", line 5, in __getattr__
    AttributeError[color=blue][color=green][color=darkred]
    >>> t.id = "something else"
    >>> t.id[/color][/color][/color]
    'something else'[color=blue][color=green][color=darkred]
    >>> t.whatever = "something else"[/color][/color][/color]
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    AttributeError: 'T' object has no attribute 'whatever'

    Peter

    Comment

    Working...