При использовании __new__ для настройки создания метакласса мы можем передавать атрибуты методу type () .__ new__, который будет установлен для объекта до его возвращения, например,
class Foo(type):
def __new__(cls, name, bases, attrs):
attrs['customAttr'] = 'someVal'
return type.__new__(cls, name, bases, attrs)
Так что:
>> Foo.__dict__
{'customeAttr': 'someVal', ...}
Однако я не знаю, как сделать то же самое для обычного (не мета) класса, что вызывает проблему при использовании __setattr __:
class Bar(object):
def __new__(cls, someVal):
obj = object().__new__(cls) # cant pass custom attrs
obj.customAttr = someVal # obj is already a Bar and invokes __setattr__
return obj
def __setattr__(*args): raise Exception('read-only class')
Так что к сожалению:
>>> Bar(42)
...
Exception: read-only class
В __new__ из Bar я возвращаю полноценный экземпляр класса из object (), и любой доступ к атрибуту проходит через обычные правила поиска, в этом случае вызывая __setattr__. Metaclass Foo избегает этого, так как type () будет устанавливать атрибуты перед возвратом экземпляра во время низкоуровневого создания, тогда как object () не будет.
Есть ли способ передачи атрибутов в object () или другой тип, который я могу использовать в качестве экземпляра, возвращенного из __new__, который позволяет устанавливать атрибуты до того, как он станет полным экземпляром класса? Меня не интересуют такие решения, как установка __class__ после создания экземпляра.