2017-01-15 2 views
2

Я хочу написать сценарий clean up, чтобы избежать неожиданного импорта Python.Найти все пакеты python в проекте

Для лучшего понимания, я покажу вам свои варианты использования.

Иногда мы имеем ситуацию, когда наши папки проекта содержит:

... 
my_project/custom.py 
my_project/custom/__init__.py 
... 

Если вы пытаетесь импортировать что-то:

from my_project.custom import some_func 

он импортирует из файла custom.py пользовательского каталога вместо.

Я хочу избежать такой ситуации и добавить крючок для проверки, если в родительском каталоге какого-либо пакета python нет файла python (папка с init .py-файл).

Возникает вопрос: Что это самый простой способ, чтобы найти все пакеты Python в моем проекте (все каталоги с инициализации файл .py)

Есть много библиотек Python как: imp, modulefinder ..., но я не уверен, что они могут просто проверить, если папка является модуль питона с помощью FULLPATH (без загрузки этого пакета)

в конечном итоге я хочу сделать что-то вроде этого:

import os 
for folder, sub, files in os.walk('/my/project/root/path'): 
    # not sure folder or sub, but it doesn't matter 
    if is_python_module(folder): 
     # do some stuff 

Похоже, я нашел решение:

for folder, sub, file in os.walk(path): 
    try: 
     _, module, _ = imp.find_module(folder) 
     print "Module: %s" % module 
    except ImportError: 
     pass 

Если есть лучшие решения, не стесняйтесь сказать!

+1

Я знаю, что это семантика, но каталог («папка»), содержащий модули и файл '__init __. Py', называется * пакетом *. Почему вы хотите избежать этой ситуации, в чем проблема? – cdarke

+0

@cdarke, я хочу избежать этой ситуации, потому что, если в вашей первой реализации у вас есть файл custom.py и у вас еще нет пользовательского пакета, все ваши импортные данные импортируются из файла custom.py. Если вы добавите настраиваемую папку (пакет), все ваши старые импорты будут иметь неожиданное поведение. – smart

+0

Поэтому не добавляйте индивидуальный пакет с тем же именем. Извините, что звучит легкомысленно. Коллизии имен не просто зарезервированы для имен модулей/пакетов - кто знает количество сообщений на этом сайте, где кто-то назвал их сценарий так же, как стандартный библиотечный модуль, или дал «переменную» то же имя, что и встроенная функция или класса. Да, это проблема, но она решена с помощью хорошего кода и управления проектами. – cdarke

ответ

3

Во-первых, вы путаете терминологию:

  • каталог с __init__.py файл называется пакет; my_project/custom/ - пакет Python
  • модули - это файлы, содержащие код Python; my_project/custom.py представляет собой модуль Python

Во-вторых, я бы лучше использовать в os.walk - следующий код гораздо понятнее в своих намерениях имхо:

import os 
for dirpath, dirnames, filenames in os.walk(some_dir): 
    if '__init__.py' in filenames: 
     # do stuff 

EDIT: link к документации

0

The следующий код может быть полезен. Я написал это, чтобы помочь понять недокументированный старый код, который довольно часто использовал import .... as .... Он напрямую не связан с проблемами __init__.py, но отчет может помочь. Все, что он делает, - это итерация через ваше местное пространство имен.

Сначала я создаю модуль под названием «spection.ру»(можно назвать что угодно):

""" 
Python 2 version 
10.1.14 

""" 
import inspect 
import sys 
import re 

def look(): 

    for name, val in sys._getframe(1).f_locals.items(): 

     if inspect.ismodule(val): 

      fullnm = str(val) 

      if not '(built-in)' in fullnm and \ 
       not __name__  in fullnm: 
       m = re.search(r"'(.+)'.*'(.+)'", fullnm) 
       module,path = m.groups() 
       print "%-12s maps to %s" % (name, path) 

Теперь в модуле вы хотите проверить добавить после импорта, вероятно, в„основной()“, если у вас есть один:

import spection 
spection.look() 

Если модуль загружается из имени файла .py, то вы должны получить что-то вроде этого:

custom  maps to myproject/custom.pyc 

Если модуль запускается с __init__.py вы получите что-то вроде этого:

custom  maps to myproject/custom/__init__.pyc 

Функция должна делать это для всех модулей (кроме встроенных команд), импортируемых в точке, которую вы называете section.look(). Отображаются файлы .pyc, это будет файл .py при первом использовании этого модуля.

Вот код, который я использовал для тестирования:

import sys 
sys.path.append('myproject') 
import custom 

import spection 
spection.look() 

Надеется, что это помогает.

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