2011-06-24 17 views
25

Quiero algo así como sys.builtin_module_names excepto para la biblioteca estándar. Otras cosas que no funcionaron:¿Cómo puedo obtener una lista de todos los módulos de biblioteca estándar de Python?

  • sys.modules - sólo muestra los módulos que ya han sido cargados
  • sys.prefix - un camino que incluiría no estándar de módulos de biblioteca EDIT: y no parece que trabajar dentro de una virtualenv.

La razón por la que quiero que esta lista es para que pueda pasar a los --ignore-module o --ignore-dir opciones de línea de comandos de tracehttp://docs.python.org/library/trace.html

Así que, finalmente, me gustaría saber cómo ignorar todos los módulos estándar de la biblioteca cuando usando trace o sys.settrace.

EDITAR: Quiero que funcione dentro de un virtualenv. http://pypi.python.org/pypi/virtualenv

Edit2: Quiero que funcione para todos los entornos (es decir, a través de sistemas operativos, dentro y fuera de un virtualenv.)

+0

Este es un duplicado aproximada de http://stackoverflow.com/questions/5632980/list-of-all-imports-in- python-3, que desafortunadamente no atrajo ninguna respuesta particularmente útil hasta el momento. –

Respuesta

8

¿Por qué no resolver lo que es parte de la biblioteca estándar usted mismo?

import distutils.sysconfig as sysconfig 
import os 
std_lib = sysconfig.get_python_lib(standard_lib=True) 
for top, dirs, files in os.walk(std_lib): 
    for nm in files: 
     if nm != '__init__.py' and nm[-3:] == '.py': 
      print os.path.join(top, nm)[len(std_lib)+1:-3].replace('\\','.') 

da

abc 
aifc 
antigravity 
--- a bunch of other files ---- 
xml.parsers.expat 
xml.sax.expatreader 
xml.sax.handler 
xml.sax.saxutils 
xml.sax.xmlreader 
xml.sax._exceptions 

Editar: Es probable que desee agregar un cheque para evitar site-packages si es necesario para evitar módulos de biblioteca no estándar.

+0

'sysconfig.get_python_lib (standard_lib = True)' también me da la ruta de mi virtualenv que no tiene todos los módulos de biblioteca estándar. – saltycrane

+0

En el caso de virtualenv, puede reducir el problema para encontrar la ubicación del virtualenv, que [este hilo] (http://groups.google.com/group/python-virtualenv/browse_thread/thread/e30029b2e50ae17a) sugiere que puede se hace usando 'sys.real_prefix' (aunque no tengo una herramienta práctica para probar) – Caspar

+0

El uso de' sys.real_prefix' con virtualenv también se menciona en [esta respuesta SO] (http://stackoverflow.com/questions/1871549/python-determine-if-running-inside-virtualenv/1883251 # 1883251) – Caspar

1

Esto hará que se cierre:

import sys; import glob 
glob.glob(sys.prefix + "/lib/python%d.%d" % (sys.version_info[0:2]) + "/*.py") 

Otra posibilidad para la ignore-dir opción:

os.pathsep.join(sys.path) 
+0

Me acabo de dar cuenta de que 'sys.prefix' devuelve una ruta que no incluye la mayoría de los módulos de biblioteca estándar cuando estoy ejecutando dentro de un virtualenv. Edité mi pregunta anterior. – saltycrane

1

Consultaría la referencia de biblioteca estándar en la documentación oficial, que recorre toda la biblioteca con una sección para cada módulo. :)

4

Aquí hay una mejora en la respuesta de Caspar, que no es multiplataforma, y ​​se pierde módulos de nivel superior (por ejemplo email), módulos cargados dinámicamente (por ejemplo array), y los módulos incorporados en el núcleo (por ejemplo sys) :

import distutils.sysconfig as sysconfig 
import os 
import sys 

std_lib = sysconfig.get_python_lib(standard_lib=True) 

for top, dirs, files in os.walk(std_lib): 
    for nm in files: 
     prefix = top[len(std_lib)+1:] 
     if prefix[:13] == 'site-packages': 
      continue 
     if nm == '__init__.py': 
      print top[len(std_lib)+1:].replace(os.path.sep,'.') 
     elif nm[-3:] == '.py': 
      print os.path.join(prefix, nm)[:-3].replace(os.path.sep,'.') 
     elif nm[-3:] == '.so' and top[-11:] == 'lib-dynload': 
      print nm[0:-3] 

for builtin in sys.builtin_module_names: 
    print builtin 

Esto todavía no es perfecta, ya que se perderá cosas como os.path que se define desde dentro os.py de una manera dependiente de la plataforma a través de un código como import posixpath as path, pero es probable que sea tan bueno como te, teniendo teniendo en cuenta que Python es un lenguaje dinámico y nunca se puede saber qué módulos se definen hasta que en realidad se define en tiempo de ejecución.

2

Aquí es una respuesta 2014 a una pregunta 2011 -

El autor de isort, una herramienta que limpia las importaciones, tuvo que lidiar este mismo problema con el fin de satisfacer el requisito PEP8 que las importaciones base de la biblioteca deben ser solicitados antes importaciones de terceros.

He estado usando esta herramienta y parece estar funcionando bien. Usted puede utilizar el método place_module en el archivo isort.py, ya que es de código abierto espero que el autor no le importaría que me reproduce la lógica aquí:

def place_module(self, moduleName): 
    """Tries to determine if a module is a python std import, third party import, or project code: 

    if it can't determine - it assumes it is project code 

    """ 
    if moduleName.startswith("."): 
     return SECTIONS.LOCALFOLDER 

    index = moduleName.find('.') 
    if index: 
     firstPart = moduleName[:index] 
    else: 
     firstPart = None 

    for forced_separate in self.config['forced_separate']: 
     if moduleName.startswith(forced_separate): 
      return forced_separate 

    if moduleName == "__future__" or (firstPart == "__future__"): 
     return SECTIONS.FUTURE 
    elif moduleName in self.config['known_standard_library'] or \ 
      (firstPart in self.config['known_standard_library']): 
     return SECTIONS.STDLIB 
    elif moduleName in self.config['known_third_party'] or (firstPart in self.config['known_third_party']): 
     return SECTIONS.THIRDPARTY 
    elif moduleName in self.config['known_first_party'] or (firstPart in self.config['known_first_party']): 
     return SECTIONS.FIRSTPARTY 

    for prefix in PYTHONPATH: 
     module_path = "/".join((prefix, moduleName.replace(".", "/"))) 
     package_path = "/".join((prefix, moduleName.split(".")[0])) 
     if (os.path.exists(module_path + ".py") or os.path.exists(module_path + ".so") or 
      (os.path.exists(package_path) and os.path.isdir(package_path))): 
      if "site-packages" in prefix or "dist-packages" in prefix: 
       return SECTIONS.THIRDPARTY 
      elif "python2" in prefix.lower() or "python3" in prefix.lower(): 
       return SECTIONS.STDLIB 
      else: 
       return SECTIONS.FIRSTPARTY 

    return SECTION_NAMES.index(self.config['default_section']) 

Obviamente es necesario utilizar este método en el contexto de la clase y la archivo de configuración Eso es básicamente una alternativa en una lista estática de importaciones conocidas de lib core.

# Note that none of these lists must be complete as they are simply fallbacks for when included auto-detection fails. 
default = {'force_to_top': [], 
      'skip': ['__init__.py', ], 
      'line_length': 80, 
      'known_standard_library': ["abc", "anydbm", "argparse", "array", "asynchat", "asyncore", "atexit", "base64", 
             "BaseHTTPServer", "bisect", "bz2", "calendar", "cgitb", "cmd", "codecs", 
             "collections", "commands", "compileall", "ConfigParser", "contextlib", "Cookie", 
             "copy", "cPickle", "cProfile", "cStringIO", "csv", "datetime", "dbhash", "dbm", 
             "decimal", "difflib", "dircache", "dis", "doctest", "dumbdbm", "EasyDialogs", 
             "errno", "exceptions", "filecmp", "fileinput", "fnmatch", "fractions", 
             "functools", "gc", "gdbm", "getopt", "getpass", "gettext", "glob", "grp", "gzip", 
             "hashlib", "heapq", "hmac", "imaplib", "imp", "inspect", "itertools", "json", 
             "linecache", "locale", "logging", "mailbox", "math", "mhlib", "mmap", 
             "multiprocessing", "operator", "optparse", "os", "pdb", "pickle", "pipes", 
             "pkgutil", "platform", "plistlib", "pprint", "profile", "pstats", "pwd", "pyclbr", 
             "pydoc", "Queue", "random", "re", "readline", "resource", "rlcompleter", 
             "robotparser", "sched", "select", "shelve", "shlex", "shutil", "signal", 
             "SimpleXMLRPCServer", "site", "sitecustomize", "smtpd", "smtplib", "socket", 
             "SocketServer", "sqlite3", "string", "StringIO", "struct", "subprocess", "sys", 
             "sysconfig", "tabnanny", "tarfile", "tempfile", "textwrap", "threading", "time", 
             "timeit", "trace", "traceback", "unittest", "urllib", "urllib2", "urlparse", 
             "usercustomize", "uuid", "warnings", "weakref", "webbrowser", "whichdb", "xml", 
             "xmlrpclib", "zipfile", "zipimport", "zlib", 'builtins', '__builtin__'], 
      'known_third_party': ['google.appengine.api'], 
      'known_first_party': [], 

--- --- cortar

que ya era una hora en la escritura de esta herramienta para mí antes de que me encontré con el módulo iSort, así que espero que esto también puede ayudar a alguien más para evitar la re-inventar ¡la rueda!

21

Si alguien todavía está leyendo esto en 2015, me encontré con el mismo problema, y ​​no me gustó ninguna de las soluciones existentes. Entonces, lo forcé brutalmente escribiendo algún código para raspar el TOC de la página Biblioteca estándar en los documentos oficiales de Python. También construí una API simple para obtener una lista de bibliotecas estándar (para Python versión 2.6, 2.7, 3.2, 3.3 y 3.4).

El paquete es here, y su uso es bastante simple:

>>> from stdlib_list import stdlib_list 
>>> libraries = stdlib_list("2.7") 
>>> libraries[:10] 
['AL', 'BaseHTTPServer', 'Bastion', 'CGIHTTPServer', 'ColorPicker', 'ConfigParser', 'Cookie', 'DEVICE', 'DocXMLRPCServer', 'EasyDialogs'] 
+1

¡La mejor solución! ¡¡¡Muchas gracias!!! – ragesz

Cuestiones relacionadas