Просто добавьте сюда несколько заметок:
Создатель Python, Гвидо ван Россум, утверждает, что он фактически создал слотов для более быстрого доступа к атрибутам.
из книги Свободный питон , __slots__
используется для более быстрого доступа к атрибутам и сокращения использования памяти, чтобы не мешать пользователю добавлять дополнительные атрибуты.
проверьте этот код:
class MyClass:
__slots__ = ['defined_var', '__dict__']
obj = MyClass()
obj.undefined_var = 3 # works fine
Проблема в использовании __slots__
. Если вы создаете подкласс этого класса, вам нужно повторить в нем атрибут __slot__
.
class MyClass:
__slots__ = ['defined_var']
class MySubClass(MyClass):
# you need to redefine the __slots__ here too
pass
obj = MyClass()
sub_obj = MySubClass()
sub_obj.undefined_var = 3 # works fine not excepting this
obj.undefined_var = 3 # throw exception
Итак, если вам действительно это нужно, перейдите к переопределению метода setattr
, как предложил @Olvin Roght.
class MyClass:
x = None
def __setattr__(self, key, value):
if hasattr(self, key):
object.__setattr__(self, key, value)
else:
raise AttributeError(f"\"{key}\" is not defined in \"{self.__class__.__name__}\"")
class MySubClass(MyClass):
pass
obj = MyClass()
sub_obj = MySubClass()
sub_obj.x = 3 # works fine
obj.x = 3 # works fine
sub_obj.undefined_var = 3 # error
obj.undefined_var = 3 # error
Если когда-нибудь вы захотите сделать исправление обезьян на вашем объекте:
obj = MyClass()
obj.__dict__['z'] = 4
print(obj.z) # print 4, we added a new attribute
Так что не беспокойтесь о том, что клиент не сможет добавить новый атрибут, это плохая привычка. и вы не позволите себе контролировать свой объект и изменить его поведение, устраняя гибкость, которую дает вам python, зачем вам это нужно.