0

How to protect class from adding attributes in that way:

class foo(object):
     pass

x=foo()
x.someRandomAttr=3.14
8
  • 1
    Use __slots__ = () in class definition. See slots. Commented Oct 26, 2013 at 14:06
  • 1
    @falsetru: That is a side-effect, however. Commented Oct 26, 2013 at 14:12
  • Do you want an object without any attributes? Then just use x = object(). Commented Oct 26, 2013 at 14:14
  • @MartijnPieters - No, I think he is making a class and wants it so that nobody can add anything to it. In other words, you get only what comes with the class (or namely what he put in it). Commented Oct 26, 2013 at 14:16
  • @iCodez: That's why I made that a comment; the question is rather sparse on details. Commented Oct 26, 2013 at 14:19

2 Answers 2

4

If you want an immutable object, use the collections.namedtuple() factory to create a class for you:

from collections import namedtuple

foo = namedtuple('foo', ('bar', 'baz'))

Demo:

>>> from collections import namedtuple
>>> foo = namedtuple('foo', ('bar', 'baz'))
>>> f = foo(42, 38)
>>> f.someattribute = 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'foo' object has no attribute 'someattribute'
>>> f.bar
42

Note that the whole object is immutable; you cannot change f.bar after the fact either:

>>> f.bar = 43
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
Sign up to request clarification or add additional context in comments.

Comments

3

Override the __setattr__ method:

>>> class Foo(object):
    def __setattr__(self, var, val):
        raise TypeError("You're not allowed to do this")
...     
>>> Foo().x = 1
Traceback (most recent call last):
  File "<ipython-input-31-be77d2b3299a>", line 1, in <module>
    Foo().x = 1
  File "<ipython-input-30-cb58a6713335>", line 3, in __setattr__
    raise TypeError("You're not allowed to do this")
TypeError: You're not allowed to do this

Even Foo's subclasses will raise the same error:

>>> class Bar(Foo):
    pass
... 
>>> Bar().x = 1
Traceback (most recent call last):
  File "<ipython-input-35-35cd058c173b>", line 1, in <module>
    Bar().x = 1
  File "<ipython-input-30-cb58a6713335>", line 3, in __setattr__
    raise TypeError("You're not allowed to do this")
TypeError: You're not allowed to do this

3 Comments

This prevents you from setting any attributes, including in __init__().
@chepner -you can still set attrs through the ____dict___. Ugly, but doable.
@chepner: What @tdelaney meant was you simply need to use self.__dict__['<attribute-name>'] = <whatever>. It's a well-know technique used in classes that redefine __setattr__.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.