神奇的__init__

__init__一般在两种情况下会出现,第一种是以在class(类)当中以函数形式出现,如下:

1
2
3
4
class test(object):
def __init__(self,name,age):
self.name = name
self.age = age

第二种情况则是以__init__.py文件的形式出现在文件夹下。两种不同的情况虽然使用了相同名字的定义,但是其作用可以说类似又可以说不同。

def __init__(self)

__init__属于魔法函数的一种,之所以说是一种其原因是因为魔法函数是一个大家族,常见的:__ str__()、__ new__()、__ unicode__()、__ call__()、__ len__()、__repr__()等等都是魔法函数,

什么是魔法函数?

魔法函数一种python的高级用法,一般情况下不是很常见,魔法函数允许使用者在定义类的时候将其绑定在其中,一般格式以两个下划线开始并以两个下划线结束。以__init__为例,该函数允许在实例化类的时候给变量申请内存空间并赋予初始值,有时候我们会将其称之为构造函数。

魔法函数具有以下特点:

  • Python中以双下划线(xx)开始和结束的函数(不可自己定义)为魔法函数。
  • 调用类实例化的对象的方法时自动调用魔法函数。
  • 在自己定义的类中,可以实现之前的内置函数。

__init__是什么?

__init__函数存在于class当中,可以包含多个参数,但是必须有一个self作为参数,__init__的存在使得函数在初始化的时候就能够给对象当中的参数进行初始化并赋值,在初始化的时候程序会自动调用该函数,于此同事,如果设置了__init__的参数,在实例化的时候如果不给定参数也是错误的。当然,__init__也是作为类的私有函数存在,所以在实例化之后是无法被外部调用的。

__init__.py

__init__函数可以当中构造函数来理解,但是__init__.py却不是那么容易理解。

定义

常见的说法会将其描述成为:__init__.py 文件的作用是将文件夹变为一个Python模块,Python 中的每个模块的包中,都有__init__.py 文件。


但是直接跳到python模块上来,这样的理解未免太过于快了,以至于很多人不能够理解。因此我打算在这里只说用法方便于理解。

用法

假设现在有这样一个目录:

1
2
3
4
5

├─model
│ info.py

test.py

现在model.py文件当中的代码是这样的:

1
2
3
4
a = 1

def test(param):
return param

那么问题来了,我们该怎么去调用model.py文件当中的变量?


以前的方法是from model.model import * ,但是如果,下面不止这一个文件呢?万一这个目录下有很多个文件呢?我们再去一个个去调用,未免太过于难受了。
但是如果我们在model目录下添加一个__init__.py文件,在文件当中写入:

1
2
3
from .info import test

test = test

然后在test.py文件当中写入:

1
2
3
import model

print(model.test('a'))

这样就能够直接调用了。发现端倪了吗?这里我们使用的就是import model,没有指定那一个文件啊,按照一般的想法不应该是import model.__init__吗?
这就是所谓的将文件夹变成一个模块的含义,__init__.py文件的存在能够管理该文件夹下面的所有文件,并且通过__init__.py文件导入的形式,在调用文件夹的时候自动调用__init__.py文件下管理文件当中的对象。但是这样的做法有什么含义?用处在于什么?用其他文件不能实现吗?


首先,这样能够更加有效的管理文件夹下面的文件,对于使用者来说能够将文件夹当作一个封闭的包使用,不用担心导入存在的路径问题,在封装跟打包的时候也能够保证调用的可靠性。当然其他随便写个文件也能够实现类似的功能,但是使用起来完全没有__init__.py文件方便,并且可能存在未知的导入出错问题。