我为什么要在__init__.py文件中放入python代码


73

我正在寻找要在__init__.py文件中放入哪种类型的代码,以及与此相关的最佳实践是什么。还是一般来说是不好的做法?

任何对解释这一点的已知文件的引用也将不胜感激。


Answers:


65

库和框架通常使用__init__.py文件中的初始化代码来巧妙地隐藏内部结构并为用户提供统一的界面

让我们以Django表单模块为例。表单模块中的各种功能和类基于它们的分类在不同的文件中定义。

forms/
  __init__.py
  extras/
    ...
  fields.py
  forms.py
  widgets.py
  ...

现在,如果要创建表单,则必须知道每个函数都在哪个文件中定义,并且用于创建联系表单的代码必须看起来像这样(不方便且丑陋)。

 class CommentForm(forms.forms.Form):
    name = forms.fields.CharField() 
    url = forms.fields.URLField()
    comment = forms.fields.CharField(widget=forms.widgets.Textarea) 

相反,在Django中,您可以直接从表单名称空间引用各种窗口小部件,表单,字段等。

from django import forms

class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField(widget=forms.Textarea)

这怎么可能?为了实现这一点,Django在forms/__init__.py文件中添加了以下语句,该语句将所有小部件,表单,字段等导入forms名称空间。

from widgets import *
from fields import *
from forms import *
from models import *

如您所见,这简化了创建表单的过程,因为现在您不必担心每个函数/类的定义位置,而只需直接从forms名称空间使用所有这些即可。这只是一个示例,但是您可以在其他框架和库中看到类似的示例。


11

该领域的最佳实践之一是从库中导入所有需要的类(例如,查看mongoengine)。因此,您图书馆的用户可以执行以下操作:

from coollibrary import OneClass, SecondClass

代替

from coollibrary.package import OneClass
from coollibrary.anotherpackage import SecondClass

此外,良好的做法包括在__init__.py版本常量中


您所说的版本常数是什么意思?你能把这句话说清楚吗?
thanos.a

5
  1. 为方便起见:其他用户将不需要知道您的功能的确切位置。

    your_package/
      __init__.py
      file1.py/
      file2.py/
        ...
      fileN.py
    
    # in __init__.py
    from file1 import *
    from file2 import *
    ...
    from fileN import *
    
    # in file1.py
    def add():
        pass
    

    然后其他人可以通过以下方式调用add()

    from your_package import add
    

    不知道file1,例如

    from your_package.file1 import add
    
  2. 放一些东西进行初始化。例如,日志记录(应该放在顶层):

    import logging.config
    logging.config.dictConfig(Your_logging_config)
    
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.