我想知道__init__和__call__方法之间的区别。

例如:

class test:

  def __init__(self):
    self.a = 10

  def __call__(self): 
    b = 20

当前回答

在Python中,函数是一级对象,这意味着:函数引用可以在输入中传递给其他函数和/或方法,并在它们内部执行。

类的实例(又名对象),可以像函数一样对待:将它们传递给其他方法/函数并调用它们。为了实现这一点,__call__类函数必须特殊化。

Def __call__(self, [args…]) 它接受可变数量的参数作为输入。假设x是类x的实例,x.__call__(1,2)类似于将x(1,2)或实例本身作为函数调用。

在Python中,__init__()被正确地定义为类构造函数(以及__del__()是类析构函数)。因此,在__init__()和__call__()之间有一个净区别:第一个创建Class的实例,第二个使该实例可以像函数一样被调用,而不会影响对象本身的生命周期(即__call__不影响构建/销毁生命周期),但它可以修改其内部状态(如下所示)。

的例子。

class Stuff(object):

    def __init__(self, x, y, range):
        super(Stuff, self).__init__()
        self.x = x
        self.y = y
        self.range = range

    def __call__(self, x, y):
        self.x = x
        self.y = y
        print '__call__ with (%d,%d)' % (self.x, self.y)

    def __del__(self):
        del self.x
        del self.y
        del self.range

>>> s = Stuff(1, 2, 3)
>>> s.x
1
>>> s(7, 8)
__call__ with (7,8)
>>> s.x
7

其他回答

__call__使类的实例可调用。 为什么需要它?

从技术上讲,__init__在对象创建时由__new__调用一次,以便可以初始化它。

但是在许多情况下,您可能想要重新定义对象,例如您已经完成了对象,并且可能发现需要一个新对象。使用__call__,你可以重新定义相同的对象,就像它是新的一样。

这只是一个案例,可能还有更多。

在Python中,函数是一级对象,这意味着:函数引用可以在输入中传递给其他函数和/或方法,并在它们内部执行。

类的实例(又名对象),可以像函数一样对待:将它们传递给其他方法/函数并调用它们。为了实现这一点,__call__类函数必须特殊化。

Def __call__(self, [args…]) 它接受可变数量的参数作为输入。假设x是类x的实例,x.__call__(1,2)类似于将x(1,2)或实例本身作为函数调用。

在Python中,__init__()被正确地定义为类构造函数(以及__del__()是类析构函数)。因此,在__init__()和__call__()之间有一个净区别:第一个创建Class的实例,第二个使该实例可以像函数一样被调用,而不会影响对象本身的生命周期(即__call__不影响构建/销毁生命周期),但它可以修改其内部状态(如下所示)。

的例子。

class Stuff(object):

    def __init__(self, x, y, range):
        super(Stuff, self).__init__()
        self.x = x
        self.y = y
        self.range = range

    def __call__(self, x, y):
        self.x = x
        self.y = y
        print '__call__ with (%d,%d)' % (self.x, self.y)

    def __del__(self):
        del self.x
        del self.y
        del self.range

>>> s = Stuff(1, 2, 3)
>>> s.x
1
>>> s(7, 8)
__call__ with (7,8)
>>> s.x
7

__init__是Python类中的一个特殊方法,它是类的构造函数方法。每当构造类的对象时调用它,或者我们可以说它初始化了一个新对象。 例子:

    In [4]: class A:
   ...:     def __init__(self, a):
   ...:         print(a)
   ...:
   ...: a = A(10) # An argument is necessary
10

如果我们使用A(),它会给出一个错误 TypeError: __init__()缺少一个必需的位置参数:'a',因为它需要一个参数a,因为__init__。

……

当在Class中实现__call__时,可以帮助我们将Class实例作为函数调用调用。

例子:

In [6]: class B:
   ...:     def __call__(self,b):
   ...:         print(b)
   ...:
   ...: b = B() # Note we didn't pass any arguments here
   ...: b(20)   # Argument passed when the object is called
   ...:
20

这里如果我们使用B(),它运行得很好,因为它在这里没有__init__函数。

>>> class A:
...     def __init__(self):
...         print "From init ... "
... 
>>> a = A()
From init ... 
>>> a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: A instance has no __call__ method
>>> 
>>> class B:
...     def __init__(self):
...         print "From init ... "
...     def __call__(self):
...         print "From call ... "
... 
>>> b = B()
From init ... 
>>> b()
From call ... 
>>> 

上面已经给出了简短而甜蜜的答案。我想提供一些与Java相比的实际实现。

 class test(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
        def __call__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c


    instance1 = test(1, 2, 3)
    print(instance1.a) #prints 1

    #scenario 1
    #creating new instance instance1
    #instance1 = test(13, 3, 4)
    #print(instance1.a) #prints 13


    #scenario 2
    #modifying the already created instance **instance1**
    instance1(13,3,4)
    print(instance1.a)#prints 13

注意:场景1和场景2在结果输出方面似乎是相同的。 但是在场景1中,我们再次创建另一个新实例instance1。在scenario2, 我们只需修改已经创建的instance1。__call__在这里是有益的,因为系统不需要创建新的实例。

在Java中等价

public class Test {

    public static void main(String[] args) {
        Test.TestInnerClass testInnerClass = new Test(). new TestInnerClass(1, 2, 3);
        System.out.println(testInnerClass.a);

        //creating new instance **testInnerClass**
        testInnerClass = new Test().new TestInnerClass(13, 3, 4);
        System.out.println(testInnerClass.a);

        //modifying already created instance **testInnerClass**
        testInnerClass.a = 5;
        testInnerClass.b = 14;
        testInnerClass.c = 23;

        //in python, above three lines is done by testInnerClass(5, 14, 23). For this, we must define __call__ method

    }

    class TestInnerClass /* non-static inner class */{

        private int a, b,c;

        TestInnerClass(int a, int b, int c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }
    }
}