2013-06-04 5 views
1

Внутри пакета Я использую несколько проверок внутри каждого каталога модуля __init__.py, чтобы узнать, является ли среда работоспособной, и затем используйте from . import mod1 для вложенных модулей (mod1 здесь). Каждый из каталогов модулей, в свою очередь, содержит __init__.py (очевидно), который будет импортировать следующий нижний уровень (если есть).Каковы правила для __all__ и относительного импорта?

Некоторые из __init__.py содержат __all__ массивы, чтобы выставлять определенные имена только на import.

Допустим, у меня есть следующий "главный" сценарий (spam.py):

import os, sys 

if (sys.version_info[0] != 2) or (sys.version_info < (2,7)): 
    sys.exit("...") 
else: 
    import pkgname 

def main(): 
    pass 

if __name__ == '__main__': 
    main() 

и следующие pkgname/__init__.py:

import sys 
if __name__ == '__main__': 
    sys.exit(0) 
else: 
    from . import db 
    from os.path import dirname, realpath 
    sys.modules[__name__].__all__ = ['inipath'] 
    sys.modules[__name__].__dict__['inipath'] = dirname(realpath(__file__)) + '.ini' 

и следующий pkgname/db/__init__.py:

import sys 
if __name__ == '__main__': 
    sys.exit(0) 
else: 
    import sqlite3 
    # ... 
foobar = { 'spam' : 'egg' } 

__all__ = ["foobar"] 

будет символ pkgname.db.foobar будет виден de несмотря на массив __all__ в pkgname/__init__.py? То есть массив __all__ влияет только на непосредственный модуль, а также на любой нижний уровень?

Какие правила регулируют поведение Python здесь? Я попробовал несколько поисков, но пришел с пустыми руками. Возможно, я использовал неправильные запросы (__all__, python, relative import)?

ответ

3

__all__ не влияет на случай, который вы описываете. Это влияет только на то, что происходит, когда вы делаете from package import *. См. the documentation, а также previousquestions (который я нашел по поисковому запросу python __all__).

+0

Я использовал все поисковые термины в различных комбинациях, но не придумал эту ссылку. Благодарю. Также спасибо за быстрый ответ. Так что, как я понимаю, теперь '__all__' относится только к' * ', ни в коем случае. – 0xC0000022L

Смежные вопросы