代码之家  ›  专栏  ›  技术社区  ›  user697911

__init__方法如何使用_调用_方法?

  •  0
  • user697911  · 技术社区  · 7 年前

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

    例如:

    class test:
    
      def __init__(self):
        self.a = 10
    
      def __call__(self): 
        b = 20
    
    0 回复  |  直到 7 年前
        1
  •  924
  •   Cat Plus Plus    5 年前

    第一个用于初始化新创建的对象,并接收用于初始化的参数:

    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__
    
        2
  •  311
  •   Paolo Maresca avasal    11 年前

    定义一种习惯 __call__() 方法允许类的实例作为函数调用,而不总是修改实例本身。

    In [1]: class A:
       ...:     def __init__(self):
       ...:         print "init"
       ...:         
       ...:     def __call__(self):
       ...:         print "call"
       ...:         
       ...:         
    
    In [2]: a = A()
    init
    
    In [3]: a()
    call
    
        3
  •  108
  •   Matthieu Brucher    7 年前

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

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

    def __call__(self, [args ...]) 它接受数量可变的参数作为输入。假设 x 作为班级的一个例子 X , x.__call__(1, 2) 类似于打电话 x(1,2) 实例本身就是一个函数 .

    在Python中, __init__() 正确定义为类构造函数(以及 __del__() 是类析构函数)。因此,两者之间存在净区别 __初始化 __call__() :第一个创建类up的实例,第二个创建这样的实例 可呼叫 作为一种功能,它不会影响对象本身的生命周期(即。 __打电话__ 不会影响构建/销毁生命周期),但可以修改其内部状态(如下所示)。

    实例

    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
    
        4
  •  34
  •   Hamster Hooey    8 年前

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

    从技术上讲 __init__ 有人打过一次电话 __new__ 创建对象时,以便可以初始化它。

    但是在很多情况下,你可能想要重新定义你的对象,比如你已经完成了你的对象,并且可能会发现需要一个新的对象。具有 __打电话__ 可以将同一对象重新定义为新对象。

    这只是一种情况,可能还有更多。

        5
  •  28
  •   Jobin    10 年前
    >>> 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 ... 
    >>> 
    
        6
  •  20
  •   Vikram    14 年前

    __init__ 将被视为构造函数 __call__ 方法可以与对象一起调用任意次数。二者都 __初始化__ __打电话__ 函数确实采用默认参数。

        7
  •  17
  •   Ruthvik Vaila    6 年前

    我将尝试用一个例子来解释这一点,假设您想要打印fibonacci数列中固定数量的项。记住斐波那契级数的前两项是1。例:1、1、2、3、5、8、13。。。。

    您希望包含斐波那契数的列表只初始化一次,然后更新。现在我们可以使用 __call__ 功能。阅读@mudit verma的答案。就像你希望对象可以作为函数调用,但不是每次调用时都重新初始化。

    如:

    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)
    

    输出为:

    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__ 只调用了一次,也就是第一次实例化类的时候,之后在没有重新初始化的情况下调用对象。

        8
  •  11
  •   Dmitriy Sintsov    8 年前

    __call__ 允许返回任意值,而 __init__ 作为构造函数,隐式返回类的实例。正如其他答案正确指出的那样, __初始化__ 只需要打一次电话就可以了 __打电话__ 多次,以防初始化实例被分配给中间变量。

    >>> 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'
    >>> 
    
        9
  •  8
  •   Teoman shipahi    8 年前

    你也可以使用 __call__ 有利于实施的方法 decorators .

    这个例子取自 Python 3 Patterns, Recipes and Idioms

    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")
    

    输出

    enter image description here

        10
  •  8
  •   Redowan Delowar    6 年前

    所以 __init__ 在创建任何类的实例并初始化实例变量时调用。

    例子:

    class User:
    
        def __init__(self,first_n,last_n,age):
            self.first_n = first_n
            self.last_n = last_n
            self.age = age
    
    user1 = User("Jhone","Wrick","40")
    

    __call__ 当您像调用任何其他函数一样调用对象时调用。

    例子:

    class USER:
        def __call__(self,arg):
            "todo here"
             print(f"I am in __call__ with arg : {arg} ")
    
    
    user1=USER()
    user1("One") #calling the object user1 and that's gonna call __call__ dunder functions
    
        11
  •  4
  •   Uddhav P. Gautam    8 年前

    上面已经给出了简短而甜蜜的答案。我想提供一些与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中,我们再次创建另一个新实例 实例1 .在场景2中, 我们只需修改已经创建的 实例1 . __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;
            }
        }
    }
    
        12
  •  4
  •   bhatnaushad    7 年前

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

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

    如果我们使用A(),它将给出一个错误 TypeError: __init__() missing 1 required positional argument: 'a' 因为它需要一个参数 a 因为 __初始化__ .

    ........

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

    例子:

    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(),它运行得很好,因为它没有 __初始化__ 在这里起作用。

        13
  •  3
  •   HoangYell    5 年前

    案例1:

    class Example:
        def __init__(self, a, b, c):
            self.a=a
            self.b=b
            self.c=c
            print("init", self.a, self.b, self.c)
    

    运行:

    Example(1,2,3)(7,8,9)
    

    结果:

    - init 1 2 3
    - TypeError: 'Example' object is not callable
    

    class Example:
        def __init__(self, a, b, c):
            self.a=a
            self.b=b
            self.c=c
            print("init", self.a, self.b, self.c)
        def __call__(self, x, y, z):
            self.x=x
            self.y=y
            self.z=z
            print("call", self.x, self.y, self.z)
    

    运行:

    示例(1,2,3)(7,8,9)
    

    结果:

    - init 1 2 3
    - call 7 8 9
    
        14
  •  2
  •   Abhishek Jain    9 年前

    我们可以使用 呼叫 方法将其他类方法用作静态方法。

    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")  
    
        15
  •  1
  •   shaila    4 年前

    呼叫 方法用于使对象的行为类似于函数。

    >>> 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
    
    <*There is no __call__ method so it doesn't act like function and throws error.*>
    
    >>> 
    >>> class B:
    ...     def __init__(self):
    ...         print "From init ... "
    ...     def __call__(self):
    ...         print "From call it is a function ... "
    ... 
    >>> b = B()
    From init ... 
    >>> b()
    From call it is a function... 
    >>> 
    
    <* __call__ method made object "b" to act like function *>
    

    我们还可以将其传递给类变量。

    class B:
        a = A()
        def __init__(self):
           print "From init ... "