关于python: __init__ 和 __call__的区别是什么?

What is the difference between __init__ and __call__?

我想知道__init____call__方法之间的区别。

例如:

1
2
3
4
5
6
7
class test:

  def __init__(self):
    self.a = 10

  def __call__(self):
    b = 20


第一个是用来initialise新建对象的创建,和receives arguments以前做说的: </P >

1
2
3
4
5
class Foo:
    def __init__(self, a, b, c):
        # ...

x = Foo(1, 2, 3) # __init__

第二多态函数呼叫运营商。 </P >

1
2
3
4
5
6
class Foo:
    def __call__(self, a, b, c):
        # ...

x = Foo()
x(1, 2, 3) # __call__


定义一个自定义的__call__()方法中的元级的允许类的实例是被称为作为一个函数,而不是总是修饰的实例研究。 </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
In [1]: class A:
   ...:     def __init__(self):
   ...:         print"init"
   ...:        
   ...:     def __call__(self):
   ...:         print"call"
   ...:        
   ...:        

In [2]: a = A()
init

In [3]: a()
call


在Python中,函数是第一类对象,这个函数的均值:证明人可以通过在投入与其他的功能和/或方法,和executed从在他们。 </P >

instances科类(又名对象),可以处理的作为,如果他们的功能:通他们与其他的方法/函数和呼叫他们。为了实现这个,__call__级函数的人是专业的。 </P >

def __call__(self, [args ...]) 把它作为输入变量a number of arguments。。。。。。。assuming x被一审级的xx.__call__(1, 2)是analogous的电话x(1,2)或审本身作为一个函数。 </P >

在Python中,__init__()是恰当定义的AS级constructor(AS,AS是好的__del__()类的析构函数)。因此,有一个distinction网之间的__init__()__call__():第一个builds安院审级上,第二次让这样的实例callable作为一个函数将是不impacting的lifecycle的对象本身(即__call__并不影响建设/破坏lifecycle),但它可以修改其内部状态E(如下面的节目)。 </P >

实例。 </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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__让《审一级callable。。。。。。。 为什么它会被要求??????? </P >

technically __init__被称为是一次通过__new__当面向的是创造的,所以说,它可以是主动的。 </P >

但是,有很多是在scenarios你可能想要的redefine面向你,说你做的是带着你的对象,和可能需要找到一种方法的一种新的面向。你可以用__call__redefine同样面向作为如果它是新的。 </P >

是的,这是一个案例,有很多可以做的更多。 </P >


__init__将是处理作为constructor在AS __call__方法可以称为与对象的任何数的时代。两__init____call__函数做arguments采取默认值。 </P >


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>> 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 ...
>>>


我将试着对这一explain应用实例,我们对你想打印的定点数的术语中的Fibonacci数列的系列。记得那是第一个2术语(Fibonacci系列是1s。例:1,1,2,3,5,8,13……………… </P >

你想要的列表的氟的Fibonacci数是主动的只读一次的在那之后它应该更新。现在,我们可以使用__call__功能性。读"mudit verma’s的答案。这是你想要的类的对象是callable作为一个函数,但不再主动过。你呼叫它。 </P >

例: </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Recorder:
    def __init__(self):
        self._weights = []
        for i in range(0, 2):
            self._weights.append(1)
        print self._weights[-1]
        print self._weights[-2]
        print"no. above is from __init__"

    def __call__(self, t):
        self._weights = [self._weights[-1], self._weights[-1] + self._weights[-2]]
        print self._weights[-1]
        print"no. above is from __call__"

weight_recorder = Recorder()
for i in range(0, 10):
    weight_recorder(i)

的输出是: </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
1
no. above is from __init__
2
no. above is from __call__
3
no. above is from __call__
5
no. above is from __call__
8
no. above is from __call__
13
no. above is from __call__
21
no. above is from __call__
34
no. above is from __call__
55
no. above is from __call__
89
no. above is from __call__
144
no. above is from __call__

如果你要守的产出__init__是称为只读一次的那页当类被实例化为第一次,之后,被称为是面向不再initializing。。。。。。。 </P >


你也可以使用__call__方法在实施decorators的青睐。 </P >

本实例taken从Python 3型,recipes和习语 </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class decorator_without_arguments(object):
    def __init__(self, f):
       """
        If there are no decorator arguments, the function
        to be decorated is passed to the constructor.
       """

        print("Inside __init__()")
        self.f = f

    def __call__(self, *args):
       """
        The __call__ method is not called until the
        decorated function is called.
       """

        print("Inside __call__()")
        self.f(*args)
        print("After self.f( * args)")


@decorator_without_arguments
def sayHello(a1, a2, a3, a4):
    print('sayHello arguments:', a1, a2, a3, a4)


print("After decoration")
print("Preparing to call sayHello()")
sayHello("say","hello","argument","list")
print("After first sayHello() call")
sayHello("a","different","set of","arguments")
print("After second sayHello() call")

输出: </P >

enter image description here </P >


短和甜蜜的回答是已经提供的以上。我想提供一些实际执行的是相对于与Java。 </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 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的情景的情景看来,在同一术语所产出的结果。 但在scenario1,我们创建了另一个新的instance1审。在scenario2, 我们已经创造了instance1简单的修改。__call__是beneficial这里为系统不需要创建新的实例。 </P >

在Java的当量 </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
        }
    }
}


__call__允许返回的矩的四值,当__init__被安constructor时返回的审级implicitly大学。作为其他回答恰当点式",__init__是称为只是一次,而它的可能的呼叫__call__多的时代,在案例中的主动审是分配的中间变量。 </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> class Test:
...     def __init__(self):
...         return 'Hello'
...
>>> Test()
Traceback (most recent call last):
  File"<console>", line 1, in <module>
TypeError: __init__() should return None, not 'str'
>>> class Test2:
...     def __call__(self):
...         return 'Hello'
...
>>> Test2()()
'Hello'
>>>
>>> Test2()()
'Hello'
>>>

我们可以使用呼叫的方法对使用其他类的方法为静态方法。 </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
class _Callable:
    def __init__(self, anycallable):
        self.__call__ = anycallable

class Model:

    def get_instance(conn, table_name):

       """ do something"""

    get_instance = _Callable(get_instance)

provs_fac = Model.get_instance(connection,"users")


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

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

如果我们使用一个(),它将给出一个错误TypeError: __init__() missing 1 required positional argument: 'a'由于__init__的原因,需要一个参数a

……

在类中实现时,__call__帮助我们作为函数调用调用调用类实例。

例子:

1
2
3
4
5
6
7
8
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__函数。


创建一个对象时,init方法会自动运行。它用于初始化实例变量。

1
2
3
4
5
6
7
8
9
class my_class():
    def __init__(self,a,b):
        self.a = a
        self.b = b
        print("Object was created, instance variables were initialized")

obj = my_class(1,2)  
print(obj.a)        #prints 1
print(obj.b)        #prints 2

调用方法可用于重新定义/重新初始化相同的对象。它还通过向对象传递参数,方便将类的实例/对象用作函数。

1
2
3
4
5
6
7
8
9
10
11
12
class my_class():
    def __init__(self, a,b):
        self.a=a
        self.b=b

    def __call__(self,a,b):
        Sum = a+b  
        return Sum

obj = my_class(1,2)   #  a=1, b=2
Sum = obj(4,5)        #  a=4, b=5 instance variables are re-initialized
print(Sum)            #  4 + 5= 9