[英]where does the 'self' object comes from in the method __init__?
I'm learning python and the construct method __init__
makes me confused.我正在学习 python 并且构造方法
__init__
让我感到困惑。
class Test(object):
def __init__(self):
pass
As known, python implicitly pass a parameter representing the object itself at the first place.众所周知,python 首先隐式传递代表 object 本身的参数。 It is acceptable in common member functions.
在普通成员函数中是可以接受的。 But what makes me confused is that the constructor requests an object itself.
但让我感到困惑的是,构造函数本身请求了一个 object。 It looks like the c++ code below.
它看起来像下面的 c++ 代码。 This code does not make sense!
这段代码没有意义! The parameter
thiz
does not even exit before the constructor!参数
thiz
甚至不会在构造函数之前退出!
class Test {
public:
Test(Test *thiz);
};
So, my question is, why python needs a "non-existent" self
object in constructor __init__
?所以,我的问题是,为什么 python 在构造函数
__init__
中需要一个“不存在的” self
object ?
__init__
behaves like any other normal function in a class. __init__
的行为类似于 class 中的任何其他正常 function。 It gets called by the interpreter at a special time if it is defined, but there is nothing special about it.如果它被定义,它会在一个特殊的时间被解释器调用,但它并没有什么特别之处。 You can call it any time yourself, just like a regular method.
您可以自己随时调用它,就像常规方法一样。
Here are some facts to help you see the picture:这里有一些事实可以帮助您查看图片:
Function objects are non-data descriptors in python. Function 对象是 python 中的非数据描述符。 That means that function objects have a
__get__
method, but not __set__
.这意味着 function 对象具有
__get__
方法,但没有__set__
。 And if course they have a __call__
method to actually run the function.如果他们当然有一个
__call__
方法来实际运行 function。
When you put a def
statement in a class body, it creates a regular function, just like it would elsewhere.当您将
def
语句放入 class 主体时,它会创建一个常规 function,就像在其他地方一样。 You can see this by looking at type(Test.__init__)
.您可以通过查看
type(Test.__init__)
来看到这一点。 To call Test.__init__
, you would have to manually pass in a self
parameter.要调用
Test.__init__
,您必须手动传入一个self
参数。
The magic happens when you call __init__
on an instance of Test
.当您在
Test
的实例上调用__init__
时,魔法就会发生。 For example:例如:
a = Test()
a.__init__()
This code actually calls __init__
twice (which we'll get into momentarily).这段代码实际上调用了
__init__
两次(我们稍后会介绍)。 The explicit second call does not pass in a parameter to the method.显式的第二次调用不会将参数传递给该方法。 That's because
a.__init__
has special meaning when the name __init__
is present in the class but not the instance.这是因为当名称
__init__
出现在 class 中而不是实例中时, a.__init__
具有特殊含义。 If __init__
is a descriptor, the interpreter will not return it directly, but rather will call __get__
on it and return the result.如果
__init__
是一个描述符,解释器不会直接返回它,而是会在它上面调用__get__
并返回结果。 This is called binding.这称为绑定。
a.__init__()
is roughly equivalent to type(a).__init__.__get__(a, None)()
. a.__init__()
大致相当于type(a).__init__.__get__(a, None)()
。 The call .__get__(a, None)
returns a callable object that is a bound method.调用
.__get__(a, None)
返回作为绑定方法的可调用 object。 It is like a special type of partial function, in which the first positional parameter is set to a
.就像偏 function 的一种特殊类型,其中第一个位置参数设置
a
. You can see this by checking type(a.__init__)
.您可以通过检查
type(a.__init__)
看到这一点。
The self
parameter is passed to methods as the first positional parameter. self
参数作为第一个位置参数传递给方法。 As such, it does not have to be called self
.因此,它不必称为
self
。 The name is just a convention.这个名字只是一个约定。
def __init__(this):
or def __init__(x)
would work just as well. def __init__(this):
或def __init__(x)
也可以。
Finally, let's discuss how a = Test()
ends up calling __init__
.最后,让我们讨论一下
a = Test()
是如何调用__init__
的。 Class objects are callable in python. Class 对象可在 python 中调用。 They have a class themselves, called a metaclass (usually just
type
), which actually defines a __call__
method.他们自己有一个 class ,称为元类(通常只是
type
),它实际上定义了一个__call__
方法。 When you do Test()
, you are literally calling the class.当您执行
Test()
时,您实际上是在调用 class。
By default, the __call__
method of a class looks something (very roughly approximately) like this:默认情况下,class 的
__call__
方法看起来(非常近似)如下所示:
def __call__(cls, *args, **kwargs):
self = cls.__new__(cls, *args, **kwargs)
if isinstance(self, cls):
type(self).__init__(self, *args, **kwargs)
So a new instance is only created by __new__
, not __init__
.所以一个新实例只能由
__new__
创建,而不是__init__
。 The latter is an initializer, not a constructor or allocator.后者是初始化器,而不是构造器或分配器。 In fact, as I mentioned before, you can call
__init__
as often as you like on most classes.事实上,正如我之前提到的,您可以在大多数类中尽可能频繁地调用
__init__
。 Notable exceptions include immutable built-in classes like tuple
and int
.值得注意的例外包括不可变的内置类,如
tuple
和int
。
As an initializer, __init__
obviously needs access to the object it is initializing.作为初始化器,
__init__
显然需要访问它正在初始化的 object。 Your example does nothing with self
, but it is pretty standard to set instance attributes and do something things to prep the object.您的示例对
self
没有任何作用,但设置实例属性并做一些事情来准备 object 是非常标准的。 For cases like yours, an explicit __init__
is not necessary at all, since a missing function will be found in the base class hierarchy.对于像您这样的情况,根本不需要显式的
__init__
,因为在基本 class 层次结构中会发现缺少的 function 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.