Как защитить повторно опечатки при настройке значения для членов класса?

Рассмотрим следующий пример:

class A(): def __init__(self): self.veryImportantSession = 1 a = A() a.veryImportantSession = None # ok # 200 lines below a.veryImportantSessssionnnn = 2 # I wanna exception here!! It is typo! 

Как я могу сделать так, чтобы исключение было поднято, если я попытаюсь установить элемент, который не установлен в __init__ ?

Код выше не будет терпеть неудачу, когда он будет выполнен, но дает мне время для отладки проблем.

Как и для str:

 >>> s = "lol" >>> sa = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'str' object has no attribute 'a' 

Благодаря!

Вы можете переопределить __setattr__, чтобы разрешать имена атрибутов из определенного списка.

 class A(object): def __setattr__(self, name, value): allowed = ('x',) if name in allowed: self.__dict__[name] = value else: raise AttributeError('No attribute: %s' % name) 

В операции:

 >>> a = A() >>> ax = 5 >>> a.other = 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "myc.py", line 7, in __setattr__ raise AttributeError('No attribute: %s' % name) AttributeError: No attribute: other 

Однако, как прокомментировал msw , попытки сделать Python более похожим на Java или C ++, как правило, являются плохой идеей и приведут к потере большого количества преимуществ, предоставляемых Python. Если вас беспокоит создание опечаток, которые могут быть пропущены, вы гораздо лучше тратите время на выполнение модульных тестов для своего кода, чем на попытку заблокировать использование ваших классов.

Лучший способ защитить от опечаток – использовать такой инструмент, как pyflakes или pylint – они пройдут через ваш код и a.superImportantSesssssionnnn вам, есть ли у вас переменная a.superImportantSesssssionnnn которая никогда не используется снова, а также многие другие вещи ,

Если вы настаиваете на том, чтобы делать это в коде, у вас есть два варианта:

  • (ab) использовать __slots__ – основной целью __slots__ является оптимизация памяти для тех времен, когда у вас будут сотни, тысячи или миллионы объектов, и вам нужно как можно меньше держать следы ваших объектов. Если вы __weakref__ этот маршрут, вы должны убедиться, что включить __weakref__ качестве одного из разрешенных имен, так что слабые ссылки будут продолжать работать.

  • (ab) использовать __setattr__ – основная цель __setattr__ – разрешить запуск кода для проверки, управления или иного использования данных и их размещения в правильном формате для хранения

Повторяю, эти два варианта не предназначены для использования в качестве проверки орфографии, и ваши усилия по ограничению полезности вашего кода, запретив все возможные имена атрибутов, за исключением тех, которые вы используете сами, могут не оцениваться, когда кто-то пытается поддерживать прецедент, который вы не ожидали.

Вы можете определить переменную класса __slots__ . Дополнительную информацию см. В руководстве по языку .

__slots__ работает только в классах нового стиля, поэтому вам нужен class A(object) вместо class A в этом примере.

 class A(object): __slots__ = ['x'] def __init__(self): self.x = 1 >>> a = A() >>> ax = 2 >>> ay = 2 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'A' object has no attribute 'y'