First of all, it is almost always a bad idea. If only the reason why you want to make sure that you do not make typos - there are better tools for this (think IDE or pylint). If you are 100% sure that you need this, here are two ways to do it:
The first way - you can do this using the __setattr__ method. See python __setattr__ documentation
class Person(object): def __init__(self, first_name, last_name): self.__dict__['first_name'] = first_name self.__dict__['last_name'] = last_name def __setattr__(self, name, value): if name in self.__dict__: super(Person, self).__setattr__(name, value) else: raise AttributeError("%s has no attribute %s" %(self.__class__.__name__, name))
and conclusion:
In [49]: a = Person(1, 2) In [50]: aa = 2 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <module>() ----> 1 aa = 2 /usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in __setattr__(self, name, value) 8 super(Person, self).__setattr__(name, value) 9 else: ---> 10 raise AttributeError("%s has no attribute %s" %(self.__class__.__name__, name)) AttributeError: Person has no attribute a
Alternatively, you can do this using __slots__ ( python __slots__ documentation ):
class Person(object): __slots__ = ("first_name", "last_name") def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name
output:
In [32]: a = Person("a", "b") In [33]: a.first_name Out[33]: 'a' In [34]: aa = 1 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <module>() ----> 1 aa = 1 AttributeError: 'Person' object has no attribute 'a'
The first method is more flexible, since it allows you to crack this code even further using __dict__ directly, but it will be even more wrong than now. The second approach predetermines the space for a certain number of instance variables (links), which means less memory consumption.