我想知道__init__和__call__方法之间的区别。
例如:
class test:
def __init__(self):
self.a = 10
def __call__(self):
b = 20
我想知道__init__和__call__方法之间的区别。
例如:
class test:
def __init__(self):
self.a = 10
def __call__(self):
b = 20
当前回答
__call__使类的实例可调用。 为什么需要它?
从技术上讲,__init__在对象创建时由__new__调用一次,以便可以初始化它。
但是在许多情况下,您可能想要重新定义对象,例如您已经完成了对象,并且可能发现需要一个新对象。使用__call__,你可以重新定义相同的对象,就像它是新的一样。
这只是一个案例,可能还有更多。
其他回答
__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__函数。
你也可以使用__call__方法来实现装饰器。
这个例子来自Python 3模式,食谱和习语
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")
输出:
案例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)
Run:
Example(1,2,3)(7,8,9)
结果:
- init 1 2 3
- TypeError: 'Example' object is not callable
案例2:
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)
Run:
Example(1,2,3)(7,8,9)
结果:
- init 1 2 3
- call 7 8 9
在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__将被视为构造函数,其中__call__方法可以被对象调用任意次数。__init__和__call__函数都接受默认参数。