Koustav Chanda
cuando uso python -m pip install <package>
¿en qué se diferencia eso de usar solo pip install <package>
? Del mismo modo, ¿por qué escribiría python -m pip install --upgrade pip
para actualizar Pip, en lugar de solo pip install --upgrade pip
?
Tim Skov Jacobsen
Considere el siguiente escenario.
Tienes tres versiones de Python instaladas:
- Pitón 3.7
- Pitón 3.8
- Pitón 3.9
Su versión “predeterminada” es 3.8. Es el primero que aparece en tu camino. Por lo tanto, cuando escribe python3
(Linux o Mac) o python
(Windows) en un shell, iniciará un intérprete 3.8 porque ese es el primer ejecutable de Python que se encuentra al atravesar su ruta.
Suponga que está comenzando un nuevo proyecto en el que desea usar Python 3.9. Creas un entorno virtual llamado .venv
y activarlo.
python3.9 -m venv .venv # "py -3.9" on Windows
source .venv/bin/activate # ".venv\Scripts\activate" on Windows
Ya tenemos activado el entorno virtual usando Python 3.9. Mecanografía python
en un shell inicia el intérprete 3.9.
PEROsi escribes
pip install <some-package>
Entonces que versión de pip
se usa? ¿Es el pip para la versión predeterminada, es decir, Python 3.8, o la versión de Python dentro del entorno virtual?
Una manera fácil de sortear esa ambigüedad es simplemente usar
python -m pip install <some-package>
El -m
flag se asegura de que esté utilizando el pip que está vinculado al ejecutable activo de Python.
Es una buena práctica usar siempre -m
incluso si solo tiene instalada una versión global de Python a partir de la cual crea entornos virtuales.
Re. camino
La llamada camino es una lista de directorios donde su sistema busca ejecutables. Cuando escribe un comando, como python
esta lista se recorre desde el primer directorio hasta el último, buscando un nombre de archivo que coincida con el comando que escribió.
Si se encuentra el nombre de archivo/comando, el archivo coincidente se ejecuta sin tener en cuenta las posibles coincidencias posteriores. Si no se produce ninguna coincidencia, se obtiene un Command not found
o una variación del mismo. Este comportamiento es por diseño.
En los sistemas UNIX, la variable de entorno de ruta se llama $PATH
mientras que en los sistemas Windows se denomina %PATH%
Comentarios más generales sobre el -m
-bandera (diciembre de 2022)
La mayoría de las personas que ven esto probablemente querrán la explicación dada anteriormente con pip. Sin embargo, en un sentido más general, cuando se usa python -m some_module
el -m
flag hace que Python se ejecute some_module
como guión. Esto se afirma en el documentospero puede ser difícil de entender sin algunos conocimientos básicos.
¿Qué significa “ejecutar como un script”?
En Python, un módulo some_module
normalmente se importa a otro archivo de Python con un import some_module
instrucción en la parte superior del archivo de importación. Esto permite el uso de funciones, clases y variables definidas en some_module
dentro del archivo de importación. Ejecutar some_module
como un script en lugar de importarlo, definiría un if __name__ == "__main__"
bloque dentro del archivo. Este bloque se ejecuta cuando se ejecuta python some_module.py
en la línea de comando. Esto es útil porque Ud. no desea que este bloque de código se ejecute al importar a otros archivos, pero hacer desea que se ejecute cuando se invoque desde la línea de comandos.
Para los módulos dentro de su proyecto, esta construcción de secuencia de comandos/módulo debe ejecutarse tal cual, porque Python encontrará el módulo en su directorio de trabajo cuando se ejecuta desde la terminal:
python some_module.py
Pero para los módulos que forman parte de la biblioteca estándar de Python, esto no funcionará. El ejemplo de los usos de los documentos de Python timeit
(pip
funciona igual):
python3 timeit -s 'print("hello")' # 'python timeit.py ...' fails as well
Esto devuelve el error: "python: can't open file '/home/<username>/timeit': [Errno 2] No such file or directory"
Agregando el -m
bandera le dice a Python que busque en la ruta timeit.py
y ejecutar el if __name__ == "__main__"
cláusula del expediente.
python3 -m timeit -s 'print("hello")'
Esto funciona como se esperaba.
La fuente de la if __name__ == "__main__"
bloque para el módulo timeit se puede encontrar aquí.
-
Del documento de venv: “Cuando se usa desde un entorno virtual, las herramientas de instalación comunes como pip instalarán paquetes de Python en un entorno virtual sin necesidad de que se le indique explícitamente”.
– updogliu
29 de enero a las 10:56
turista
Dado que el argumento es un nombre de módulo, no debe dar una extensión de archivo (.py). El
module-name
debe ser un nombre de módulo de Python válido, pero es posible que la implementación no siempre lo imponga (por ejemplo, puede permitirle usar un nombre que incluya un guión).También se permiten nombres de paquetes. Cuando se proporciona un nombre de paquete en lugar de un módulo normal, el intérprete ejecutará
<pkg>.__main__
como módulo principal. Este comportamiento es deliberadamente similar al manejo de directorios y archivos comprimidos que se pasan al intérprete como argumento del script.
-
¿entonces esto solo ejecuta el script de python como un ejecutable normal? No entiendo cuándo usaría el
-m
bandera. Mis scripts siempre funcionan cuando los ejecuto sin ellos.–Charlie Parker
23 de abril de 2021 a las 17:21
-
No estoy seguro de cuál es la diferencia en este caso entre un módulo y un script, pero encuentro el comentario:
It's how you can run a module as a script.
python.org/dev/peps/pep-0338 ser interesante. Aunque la pregunta principal sigue siendo qué es un script y un módulo y por qué el-m
es realmente necesario.–Charlie Parker
3 de febrero de 2022 a las 19:33
si escribes python --help
Usted obtiene
// More flags above
-m mod : run library module as a script (terminates option list)
// and more flags below
Muchas cosas en una terminal le mostrarán cómo usarla si usa command --help
o man command
-
La pregunta principal sigue sin respuesta, ¿qué significa “ejecutar como un script”.
– Serge Mosín
25 de agosto de 2020 a las 18:35
-
@SergeMosin dos años y medio después y todavía nadie se ha molestado en decírnoslo…. las importaciones de python son una pesadilla y la descripción de los documentos es completamente inútil (“ejecutar como módulo”??). Sospecho que ninguna de estas personas sabe realmente lo que hace la bandera. Tal vez ya nadie se acuerde.
– Markemus
16 de agosto de 2022 a las 7:19
-
@markemus llamando
python -m pip [flags]
no tiene que dar la ruta del directorio a dondepip.py
existe o tener eso como su directorio de trabajo actual. En su lugar, Python mismo carga pip como un módulo al importarlo a través de PYTHONPATH y luego lo ejecuta, lo que también significa que pip.py o cualquier otro script que se ejecute ‘como un módulo’ no tendrá__name__ == '__main__'
cuando se carga y se ejecuta.– casi_ansiedad
9 dic 2022 a las 20:23
El -m
representa module-name
.
De Línea de comandos y entorno:
pitón [-bBdEhiIOqsSuvVWx?] [-c command | -m module-name | script | – ] [args]
ANURAG BISHT
Cuando -m
se usa con un python
instrucción en la línea de comando, seguida de una <module_name>
luego permite que el módulo se ejecute como un archivo ejecutable.
Puede consultar los documentos de python para lo mismo, o ejecutar python --help
-
¿entonces esto solo ejecuta el script de python como un ejecutable normal? No entiendo cuándo usaría el
-m
bandera. Mis scripts siempre funcionan cuando los ejecuto sin ellos.–Charlie Parker
23 de abril de 2021 a las 17:22
-
@CharlieParker Por lo que entiendo, el
-m
bandera es útil porque buscará un módulo/paquete en todas las rutas disponibles ensys.path
en lugar de solo el directorio de trabajo actual.– qwerty_url
1 de febrero de 2022 a las 22:29
-
@qwerty_url pero ¿no es eso lo que suele pasar?
–Charlie Parker
3 de febrero de 2022 a las 19:29
-
@CharlieParker no realmente, si lo intentas
python timeit
en su terminal y no hay un archivo/carpeta llamadotimeit
en su directorio de trabajo actual obtendrá unNo such file or directory
error, pero si agrega el-m
flag entonces python ejecutará el paquete timeit que viene con la biblioteca estándar– qwerty_url
18 de febrero de 2022 a las 13:42
mercado
Esta es realmente una pregunta interesante, así que exploremos el pep 338 vinculado por @jedwards en el comentario superior.
El indicador -m originalmente tenía un propósito más simple: convertir un nombre de módulo en un nombre de script. En python 2.4, el comportamiento era:
the command line is effectively reinterpreted from python <options> -m
<module> <args> to python <options> <filename> <args>.
Esto no parece muy útil, pero eso es lo que hizo en ese entonces. Pep 338 amplía aún más este comportamiento.
La semántica propuesta es bastante simple. [sic]: si se usa -m para ejecutar un módulo, los mecanismos de importación PEP 302 se usan para ubicar el módulo y recuperar su código compilado, antes de ejecutar el módulo de acuerdo con la semántica de un módulo de nivel superior.
Continúa explicando que Python identificará el paquete del que proviene el módulo, importará ese paquete usando el proceso estándar y ejecutará el módulo. Por lo que entiendo, llamar a “python3 -m package.module” es lo mismo que llamar:
python3
from package import module
El indicador -m ejecutará el módulo como __file__
y no __main__
. También insertará el directorio local en sys.path en lugar del directorio del script. Por lo tanto, rompe las importaciones relativas, aunque esto no fue intencional, por lo que los autores recomiendan usar siempre importaciones absolutas. También depende de cómo lo llames: “python3 -m paquete.módulo” no es lo mismo que “python3 -m módulo”.
En teoría, es simple: carga python e importa el módulo en lugar de volcar el código en __main__
. En la práctica eso tiene muchos efectos. Es un sistema de importación diferente que se comporta de manera diferente. Algunos de esos cambios no fueron intencionales y solo se descubrieron después de la implementación. Las importaciones de Python son un desastre y está bien estar confundido.
-
¿entonces esto solo ejecuta el script de python como un ejecutable normal? No entiendo cuándo usaría el
-m
bandera. Mis scripts siempre funcionan cuando los ejecuto sin ellos.–Charlie Parker
23 de abril de 2021 a las 17:22
-
@CharlieParker Por lo que entiendo, el
-m
bandera es útil porque buscará un módulo/paquete en todas las rutas disponibles ensys.path
en lugar de solo el directorio de trabajo actual.– qwerty_url
1 de febrero de 2022 a las 22:29
-
@qwerty_url pero ¿no es eso lo que suele pasar?
–Charlie Parker
3 de febrero de 2022 a las 19:29
-
@CharlieParker no realmente, si lo intentas
python timeit
en su terminal y no hay un archivo/carpeta llamadotimeit
en su directorio de trabajo actual obtendrá unNo such file or directory
error, pero si agrega el-m
flag entonces python ejecutará el paquete timeit que viene con la biblioteca estándar– qwerty_url
18 de febrero de 2022 a las 13:42
Increíble, esto es tan difícil de responder cuando algunas personas dicen que la pregunta es demasiado simple como para molestarse.
Por lo que puedo decir, el propósito práctico es que pueda usar la notación de puntos para ejecutar su script cuando no esté en el directorio.
Tu puedes correr
python -m path.to.my.happy.place
en lugar de estar en path/to/my/happy
y corriendo python place.py
-
¿Por qué querrías usar la notación de puntos? Es un desastre y no se completa automáticamente en una línea de comando.
– nedlrichards
23 oct 2022 a las 14:57
-
@nedlrichards Un ejemplo es lo que encontré donde un archivo .py que estaba ejecutando estaba en una carpeta, y la biblioteca personalizada que hice estaba en un nivel superior y luego en una carpeta diferente. Seguí encontrando errores como “Intento de importación relativa sin paquete principal conocido”. Para arreglar eso, tuve que usar el indicador -m y ejecutar mi archivo .py con dot.notation en la terminal. Se usó la misma manera para ejecutar en AWS Lambda y funcionó.
– kush
10 abr a las 14:12
Así es como puedes ejecutar un módulo como script.
– jedwards
12 de junio de 2018 a las 15:56
stackoverflow.com/questions/22241420/…
– Doctor
12 jun 2018 a las 20:24
en desacuerdo con el cierre. el cierre derrota el propósito y es una buena pregunta. Desafortunadamente las respuestas no son tan buenas.
– Robot Kansai
23 de febrero de 2020 a las 4:08
No estoy seguro de cuál es la diferencia en este caso entre un módulo y un script, pero encuentro el comentario:
It's how you can run a module as a script.
python.org/dev/peps/pep-0338 ser interesante. Aunque la pregunta principal sigue siendo qué es un script y un módulo y por qué el-m
es realmente necesario.–Charlie Parker
3 de febrero de 2022 a las 19:33
Encontré un duplicado más claro para la parte específica de Pip, así que agregué una respuesta allí y ahora engañé esto a ambas preguntas que se pueden interpretar.
– Karl Knechtel
4 de mayo a las 0:03