#python
#python
Вопрос:
Я тестирую использование метакласса и застрял при создании объекта. Новый метод выдает ошибку «отсутствуют 3 требуемых позиционных аргумента»:
bash-4.4$ python3 sftester.py
Traceback (most recent call last):
File "sftester.py", line 2, in <module>
from sorrogatefactory import make_SA_Sorrogate
File "/home/alelai/anvil9/kafka-client-new/sorrogatefactory.py", line 42, in <module>
class make_SA_Sorrogate(SA_AddOn, metaclass=SorrogateFactory()):
TypeError: __new__() missing 3 required positional arguments: 'classname', 'supers', and 'classdict'
bash-4.4$ cat sftester.py
from sorrogatefactory2 import SorrogateFactory, make_SA_Sorrogate
if __name__ == '__main__':
sa_sorrogate = make_SA_Sorrogate()
bash-4.4$ cat sorrogatefactory2.py
class SorrogateFactory(object):
def __call__(self, classname, supers, classdict):
print("In __call__")
print("Making " classname " of" " classname")
Class = self.__new__(classname, supers, classdict)
self.__init__(Class, classname, supers, classdict)
return Class
def __new__(self, classname, supers, classdict):
print("In __new__")
return type(classname, supers, classdict)
def __init__(self):
print("In __init__")
pass
class SA_AddOn(object):
pass
class make_SA_Sorrogate(SA_AddOn, metaclass=SorrogateFactory()):
def dumb(slef):
pass
Похоже, что метод _new_(), упомянутый в сообщении об ошибке, не является методом _new_() SorrogateFactory. В чем здесь подвох?
Комментарии:
1. Что такое
make_SA_Sorrogate
? Похоже, вы путаете__new__
метод метакласса (который используется для создания класса) и__new__
метод класса, созданного метаклассом (который создает экземпляр класса).2. Проверьте эту технологию с помощью видео Тима на YouTube. В котором он объяснил использование new в метаклассе.
3. @GirishDattatrayHegde: хорошее видео. Спасибо
4. @chepner: make_SA_Sorrogate должно быть make_SA_AddOn.
Ответ №1:
Вы должны сделать так, чтобы ваш метакласс наследовался от type
вместо object
.
class SorrogateFactory(type):
def __call__(self, classname, supers, classdict):
print("In __call__")
print("Making " classname " of" " classname")
Class = self.__new__(classname, supers, classdict)
self.__init__(Class, classname, supers, classdict)
return Class
def __new__(self, classname, supers, classdict):
print("In __new__")
return type(classname, supers, classdict)
def __init__(self):
print("In __init__")
pass
class SA_AddOn(object):
pass
Кроме того, просто используйте метакласс без скобок, иначе вы будете создавать его экземпляр. Вот почему вы получаете сообщение об ошибке о 3 параметрах.
class make_SA_Sorrogate(SA_AddOn, metaclass=SorrogateFactory):
def dumb(slef):
pass
Комментарии:
1. Первый аргумент __new__ на самом деле является классом, а не экземпляром класса. Хотя то, что у вас есть, верно, я бы написал
def __new__(cls, classname, supers, classdict):
для ясности.