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

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

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__?

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

Как с ул.:

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

Спасибо!

5
задан Ethan Furman 31 October 2011 в 05:54
поделиться

2 ответа

Вы можете переопределить __ 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()
>>> a.x = 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. Если вас беспокоят опечатки, которые могут быть пропущены, вам гораздо лучше потратить время на написание модульных тестов для вашего кода, чем на попытки ограничить использование ваших классов.

6
ответ дан 14 December 2019 в 01:01
поделиться

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

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

class A(object):
    __slots__ = ['x']
    def __init__(self):
        self.x = 1

>>> a = A()
>>> a.x = 2
>>> a.y = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'y'
1
ответ дан 14 December 2019 в 01:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: