Я хочу знать разницу между __init__
и __call__
методы.
Например:
class test:
def __init__(self):
self.a = 10
def __call__(self):
b = 20
Первый используется для инициализации вновь созданного объекта и получает аргументы, используемые для этого:
class Foo:
def __init__(self, a, b, c):
# ...
x = Foo(1, 2, 3) # __init__
Второй реализует функцию вызова оператора.
class Foo:
def __call__(self, a, b, c):
# ...
x = Foo()
x(1, 2, 3) # __call__
__init__
метод используется, когда класс вызывается для инициализации экземпляра, а__call__
метод вызывается, когда вызывается экземпляр__call__
?Определение пользовательского
__call__()
метода в метаклассе позволяет вызывать экземпляр класса как функцию, не всегда изменяя сам экземпляр.источник
__call__
не только позволяет использовать экземпляр в качестве функции ... он определяет тело функции, которая выполняется, когда экземпляр используется в качестве функции.В Python функции являются объектами первого класса, это означает: ссылки на функции могут быть переданы во входные данные для других функций и / или методов и выполнены внутри них.
Экземпляры Классов (или Объекты) могут рассматриваться как функции: передавайте их другим методам / функциям и вызывайте их. Для этого
__call__
функция класса должна быть специализированной.def __call__(self, [args ...])
Он принимает в качестве входных данных переменное количество аргументов. Предполагается,x
что он является экземпляром классаX
,x.__call__(1, 2)
аналогичен вызовуx(1,2)
или самому экземпляру как функции .В Python
__init__()
правильно определен как конструктор классов (равно как__del__()
и деструктор классов). Следовательно, между__init__()
и существует чистое различие__call__()
: первый создает экземпляр класса Up, второй делает такой экземпляр вызываемым, поскольку функция не влияет на жизненный цикл самого объекта (т. Е.__call__
Е. Не влияет на жизненный цикл строительства / разрушения), но он может изменить свое внутреннее состояние (как показано ниже).Пример.
источник
def __call__
просто заменим наdef update
, мы дадим классуupdate
метод, который делает то же самое. Теперь он также может изменять внутреннее состояние, если ниже вызывается какs.update(7, 8)
. Так что же, это__call__
просто сахар Синтактикс?__call__
делает экземпляр класса вызываемым. Зачем это нужно?Технически
__init__
вызывается один раз__new__
при создании объекта, чтобы его можно было инициализировать.Но есть много сценариев, когда вы можете захотеть переопределить свой объект, сказать, что вы закончили с вашим объектом и, возможно, найдете потребность в новом объекте. С помощью
__call__
него можно переопределить тот же объект, как если бы он был новым.Это только один случай, может быть еще много.
источник
источник
__init__
будет рассматриваться как конструктор, где__call__
методы могут вызываться с объектами любое количество раз. Обе функции__init__
и__call__
функции принимают аргументы по умолчанию.источник
__init__
не является функцией конструктора, но__new__
есть.__init__
называется сразу после__new__
__new__
создает экземпляр класса и получает класс в качестве аргумента, в то__init__
время как конструктор экземпляра, поэтому он получаетself
. Простой способ убедиться в этом заключается в вызовеa = Foo(1,2,3)
функции, которая получит аргументы конструктора__init__
.Я попытаюсь объяснить это на примере, предположим, что вы хотите напечатать фиксированное число терминов из ряда Фибоначчи. Помните, что первые 2 члена ряда Фибоначчи - 1 с. Например: 1, 1, 2, 3, 5, 8, 13 ....
Вы хотите, чтобы список, содержащий числа Фибоначчи, был инициализирован только один раз, и после этого он должен обновиться. Теперь мы можем использовать
__call__
функциональность. Прочитайте ответ @mudit verma. Это как если бы вы хотели, чтобы объект вызывался как функция, но не переинициализировался каждый раз, когда вы вызываете его.Например:
Выход:
Если вы заметили, что вывод
__init__
вызывался только один раз, когда экземпляр класса создавался впервые, позже объект вызывался без повторной инициализации.источник
Вы также можете использовать
__call__
метод в пользу реализации декораторов .Этот пример взят из Python 3 Patterns, Recipes and Idioms
Выход :
источник
Таким образом,
__init__
вызывается, когда вы создаете экземпляр любого класса и также инициализируете переменную экземпляра.Пример:
И
__call__
вызывается, когда вы вызываете объект, как любая другая функция.Пример:
источник
__init__
это специальный метод в классах Python, это метод конструктора для класса. Он вызывается всякий раз, когда создается объект класса или мы можем сказать, что он инициализирует новый объект. Пример:Если мы используем A (), он выдаст ошибку,
TypeError: __init__() missing 1 required positional argument: 'a'
так как требует 1 аргументаa
из-за__init__
.........
__call__
при реализации в классе помогает нам вызывать экземпляр класса как вызов функции.Пример:
Здесь, если мы используем B (), он работает просто отлично, потому что здесь нет
__init__
функции.источник
__call__
позволяет возвращать произвольные значения, в то__init__
время как конструктор неявно возвращает экземпляр класса. Как правильно указали другие ответы,__init__
вызывается только один раз, в то время как можно вызвать__call__
несколько раз, если инициализированный экземпляр назначен промежуточной переменной.источник
Короткие и приятные ответы уже приведены выше. Я хочу предоставить некоторую практическую реализацию по сравнению с Java.
Примечание : сценарий 1 и сценарий 2 выглядят одинаково с точки зрения вывода результатов. Но в сценарии 1 мы снова создаем еще один новый экземпляр instance1 . В сценарии 2 мы просто модифицируем уже созданный экземпляр 1 .
__call__
здесь выгодно, так как системе не нужно создавать новый экземпляр.Эквивалент в Java
источник
Мы можем использовать метод вызова, чтобы использовать другие методы класса в качестве статических методов.
источник