Python зависимости? - PullRequest
       4

Python зависимости?

2 голосов
/ 07 марта 2011

Можно ли программно обнаруживать зависимости по проекту Python, находящемуся в SVN?

Ответы [ 3 ]

4 голосов
/ 07 марта 2011

Вот поворот, который добавляет некоторую точность и может быть полезен, если вы обнаружите, что часто проверяете зависимости разного кода:

  • Ловит только операторы импорта, выполняемые анализируемым кодом.
  • Автоматически исключает все загруженные системой модули, так что вам не нужно проползти через него.
  • Также сообщает символы, импортированные из каждого модуля.

Код:

import __builtin__
import collections
import sys

IN_USE = collections.defaultdict(set)
_IMPORT = __builtin__.__import__

def _myimport(name, globs=None, locs=None, fromlist=None, level=-1):
    global IN_USE
    if fromlist is None:
        fromlist = []
    IN_USE[name].update(fromlist)
    return _IMPORT(name, globs, locs, fromlist, level)

# monkey-patch __import__
setattr(__builtin__, '__import__', _myimport)

# import and run the target project here and run the routine
import foobar
foobar.do_something()

# when it finishes running, dump the imports
print 'modules and symbols imported by "foobar":'
for key in sorted(IN_USE.keys()):
    print key
    for name in sorted(IN_USE[key]):
        print '  ', name

Пример foobar модуль:

import byteplay
import cjson

def _other():
    from os import path
    from sys import modules

def do_something():
    import hashlib
    import lxml
    _other()

Выход:

modules and symbols imported by "foobar":
_hashlib
array
   array
byteplay
cStringIO
   StringIO
cjson
dis
   findlabels
foobar
hashlib
itertools
lxml
opcode
   *
   __all__
operator
os
   path
sys
   modules
types
warnings
0 голосов
/ 07 марта 2011

Код Python может импортировать модули, используя строки, созданные во время выполнения, поэтому единственный верный способ - запустить код.Пример из реальной жизни: когда вы открываете базу данных с помощью dbconnect SQLAlchemy, библиотека загружает один или несколько модулей db-api в зависимости от содержимого строки вашей базы данных.

Если вы хотите запустить код, вот относительно простой способ сделать это, изучив sys.modules после его завершения:

>>> from sys import modules
>>> import codeofinterest
>>> execute_code_of_interest()
>>> print modules
[ long, list, of, loaded, modules ]

ЗдесьКроме того, вы должны иметь в виду, что теоретически это может дать сбой, если execute_code_of_interest() изменяет sys.modules, но я считаю, что это довольно редко встречается в рабочем коде.

0 голосов
/ 07 марта 2011

Абсолютно! Если вы работаете из оболочки UNIX или Linux, подойдет простая комбинация grep и awk; в общем, все, что вам нужно сделать, это искать строки, содержащие ключевое слово "import".

Однако, если вы работаете из любой среды, вы можете просто написать небольшой скрипт на Python, который будет выполнять поиск для вас (не забывайте, что строки обрабатываются как неизменяемые последовательности, поэтому вы можете сделать что-то вроде if "import" in line: ....

Единственное препятствие, связывающее эти import ed-модули с именем их пакета (первым, что приходит на ум, является модуль PIL, в Ubuntu он предоставляется пакетом python-imaging).

...