开发者

Why would I put code in __init__.py files?

I am looking for what type of code would I put in __init__.py files and what are the best practices related to this. Or开发者_高级运维, is it a bad practice in general ?

Any reference to known documents that explain this is also very much appreciated.


Libraries and frameworks usually use initialization code in __init__.py files to neatly hide internal structure and provide a uniform interface to the user.

Let's take the example of Django forms module. Various functions and classes in forms module are defined in different files based on their classification.

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

Now if you were to create a form, you would have to know in which file each function is defined and your code to create a contact form will have to look something like this (which is incovenient and ugly).

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

Instead, in Django you can just refer to various widgets, forms, fields etc. directly from the forms namespace.

from django import forms

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

How is this possible? To make this possible, Django adds the following statement to forms/__init__.py file which import all the widgets, forms, fields etc. into the forms namespace.

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

As you can see, this simplifies your life when creating the forms because now you don't have to worry about in where each function/class is defined and just use all of these directly from forms namespace. This is just one example but you can see examples like these in other frameworks and libraries.


One of the best practices in that area is to import all needed classes from your library (look at mongoengine, for example). So, a user of your library can do this:

from coollibrary import OneClass, SecondClass

instead of

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

Also, good practice is include in __init__.py version constant


  1. For convenience: The other users will not need to know your functions' exactly location.

    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
    

    then others can call add() by

    from your_package import add
    

    without knowing file1, like

    from your_package.file1 import add
    
  2. Put something for initializing. For example, the logging(this should put in the top level):

    import logging.config
    logging.config.dictConfig(Your_logging_config)
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜