#python #class #call #metaclass
#python #класс #вызов #метакласс
Вопрос:
Приведен следующий пример для экземпляра X
класса:
class X():
def __call__(self, incoming_list):
print incoming_list
X()([x for x in range(10)])
Как я могу получить тот же результат, используя __call__
магический метод из самого класса вместо экземпляра? Пример:
X([x for x in range(10)])
Вызывая напрямую, как будто переходя к __init__
. Но, прежде чем он вызовет __call__
эти вызовы __new__
, которые передают аргументы __init__
. Как я могу получить доступ к этому «метаклассу __call__
«? Возможно ли это?
Просто чтобы было легче понять, это дает мне тот же результат оттуда:
class X:
def __call__(self, incoming_list):
print incoming_list
X().__call__([x for x in range(10)])
Я хочу что-то вроде этого:
class X:
def X.__call__(incoming_list): # Syntax Error
print incoming_list
X.__call__([x for x in range(10)])
Комментарии:
1. где ваш метакласс?
2. Я не понимаю, чего вы пытаетесь достичь здесь.
def foo(xs): print(xs); foo([x for x in range(10]);
Действительно, что вы делаете со всеми этими волшебными вещами?3. … вы пытались на самом деле использовать метакласс, а не просто случайно упомянуть его в вопросе?
4. «Если вы не знаете, что такое метаклассы, вероятность того, что они вам не понадобятся, составляет 99%».
5. Класс не имеет a
__call__
, который вы можете переопределить. Вызывается конструктор классов__new__
.
Ответ №1:
Я думаю, вы считаете слишком сложным.
Возможно, вы хотите что-то вроде
class X:
def __init__(self, incoming_list):
self.data = incoming_list # to keep them for later, if needed
print incoming_list
X([x for x in range(10)])
Все без метакласса, только по определению класса.
Если вам нужен мета-класс, вы можете сделать это следующим образом
class MC(type):
def __call__(self, *a, **k):
super(MC, self).__call
print a, k
r = super(MC, self).__call__(*a, **k)
print "R", r
return r
class X(object):
__metaclass__ = MC
def __init__(self, x): print "Init", x
Используя его с
>>> X(1)
(1,) {}
Init 1
R <__main__.X object at 0x00000000022907B8>
<__main__.X object at 0x00000000022907B8>
показывает, что вызывается мета- __call__
класс, который, в свою очередь, вызывает __init__
.
Но я уверен, что вам это не нужно и что вы просто хотите __init__
.
Комментарии:
1. Спасибо! Я знаю, что мне это не нужно, мне просто было любопытно, и это было именно то, что я хотел знать.
2. Возможно
__new__
, а не__init__
в случае OP.