Puntos de entrada de Python

Muchas personas piensan que los puntos de entrada son instrucciones en setup.py que hacen que el paquete esté disponible para ejecutarse desde la línea de comandos. Esto es generalmente cierto, pero las capacidades de los puntos de entrada no se limitan a esto.

A continuación, le mostraré cómo puede implementar un sistema de complemento para un paquete para que otras personas puedan interactuar con él o, por ejemplo, expandir su funcionalidad dinámicamente.



Precaución : humor específico en lo sucesivo.

LLC "Serpiente"


Felicidades Acaba de ser nombrado jefe de Snake LLC. Esta es una posición muy responsable, no puede enfrentar la suciedad, lo que significa que debe instruir al departamento de desarrollo lo antes posible para comenzar a crear un prototipo del producto. Y así, las mejores mentes de la compañía comienzan a trabajar en snek.py:

ascii_snek = """\ --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` """ def main(): print(ascii_snek) if __name__ == '__main__': main() 

Un poco más tarde, en una reunión de accionistas, ¡demuestra con orgullo los primeros resultados!

 $ python snek.py --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` 

Serpiente como servicio


Desafortunadamente, el consumidor promedio aún no ha dominado Python y quiere ejecutar el programa desde la consola sin pensar en el intérprete o la ubicación snek.py. Bueno, nuestros mejores especialistas son los mejores que pudieron empaquetar el script para que cree automáticamente un comando de consola durante la instalación.

Para crear un paquete redistribuible, necesitamos el archivo setup.py , que contiene información sobre dependencias, licencias, etc. Además, puede especificar puntos de entrada en él:

 from setuptools import setup setup( name='snek', entry_points={ 'console_scripts': [ 'snek = snek:main', ], } ) 

console_scripts , como explicaron los expertos, es un punto de entrada especial. setuptools lee sus elementos como "<script de consola> = <ruta al objeto Python>" , creando una utilidad de consola para cada elemento al instalar el paquete.

Por ahora, instalemos el script desde las fuentes:

 $ python setup.py develop running develop running egg_info writing snek.egg-info\PKG-INFO writing dependency_links to snek.egg-info\dependency_links.txt writing entry points to snek.egg-info\entry_points.txt writing top-level names to snek.egg-info\top_level.txt reading manifest file 'snek.egg-info\SOURCES.txt' writing manifest file 'snek.egg-info\SOURCES.txt' running build_ext Creating c:\program files (x86)\py36-32\lib\site-packages\snek.egg-link (link to .) snek 0.0.0 is already the active version in easy-install.pth Installing snek-script.py script to C:\Program Files (x86)\Py36-32\Scripts Installing snek.exe script to C:\Program Files (x86)\Py36-32\Scripts Installing snek.exe.manifest script to C:\Program Files (x86)\Py36-32\Scripts Installed c:\users\rachum\notebooks Processing dependencies for snek==0.0.0 Finished processing dependencies for snek==0.0.0 

En la conferencia dedicada a los resultados del año, usted habla, demostrando el último desarrollo:

 $ snek --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` 

Una serpiente en cada casa


La serpiente conquista el mundo. La compañía realizó una OPV y fue valorada en un récord de $ 60 mil millones. Los hipster exigen una serpiente nueva, elegante, moderna y juvenil. Y si hay demanda, habrá una oferta:

 """ ASCII . : snek [--type=TYPE] """ import docopt normal_snek = """\ --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` """ fancy_snek = """\ _,..,,,_ '``````^~"-,_`"-,_ .-~c~-. `~:. ^-. `~~~-.c ; `:. `-, _.-~~^^~:. `. ; _,--~~~~-._ `:. ~. .~ `. .` ;' .:` `: `:. ` _.:-,. `. .' .: :' _.-~^~-. `. `..' .: `. ' : .' _:' .-' `. :. .: .'`. : ; : `-' .:' `. `^~~^` .:. `. ; ; `-.__,-~ ~-. ,' ': '.__.` :' ~--..--' ':. .:' ':..___.:' """ def get_sneks(): return { 'normal': normal_snek, 'fancy': fancy_snek, } def main(): args = docopt.docopt(__doc__) snek_type = args['--type'] or 'normal' print(get_sneks()[snek_type]) if __name__ == '__main__': main() 

Los inconformistas están encantados:

 $ snek --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` $ snek --type fancy _,..,,,_ '``````^~"-,_`"-,_ .-~c~-. `~:. ^-. `~~~-.c ; `:. `-, _.-~~^^~:. `. ; _,--~~~~-._ `:. ~. .~ `. .` ;' .:` `: `:. ` _.:-,. `. .' .: :' _.-~^~-. `. `..' .: `. ' : .' _:' .-' `. :. .: .'`. : ; : `-' .:' `. `^~~^` .:. `. ; ; `-.__,-~ ~-. ,' ': '.__.` :' ~--..--' ':. .:' ':..___.:' 

Serpiente transnacional


Millones de personas no pueden imaginar su día sin una serpiente. Incluso después de la adquisición de Google, los recursos de Zmeika no son suficientes para satisfacer las necesidades de los usuarios de todo el mundo. Parece que ha llegado el momento de dar a las personas la oportunidad de crear sus propias serpientes basadas en nuestra infraestructura.

 """ ASCII . : snek [--type=TYPE] """ import docopt import pkg_resources normal_snek = """\ --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` """ fancy_snek = """\ _,..,,,_ '``````^~"-,_`"-,_ .-~c~-. `~:. ^-. `~~~-.c ; `:. `-, _.-~~^^~:. `. ; _,--~~~~-._ `:. ~. .~ `. .` ;' .:` `: `:. ` _.:-,. `. .' .: :' _.-~^~-. `. `..' .: `. ' : .' _:' .-' `. :. .: .'`. : ; : `-' .:' `. `^~~^` .:. `. ; ; `-.__,-~ ~-. ,' ': '.__.` :' ~--..--' ':. .:' ':..___.:' """ def get_sneks(): sneks = { 'normal': normal_snek, 'fancy': fancy_snek, } for entry_point in pkg_resources.iter_entry_points('snek_types'): sneks[entry_point.name] = entry_point.load() return sneks def main(): args = docopt.docopt(__doc__) snek_type = args['--type'] or 'normal' print(get_sneks()[snek_type]) if __name__ == '__main__': main() 

Ahora, cada vez que se inicia snek , busca otras serpientes registradas en el sistema utilizando el punto de entrada snek_types . Cada serpiente se registra con el nombre de su tipo, lo que le permite seleccionar la serpiente deseada según los parámetros de la consola.

Todo lo más importante sucede dentro de get_sneks . Llamar a pkg_resources.iter_entry_points ('snek_types') le permite pasar por todos los puntos de entrada registrados con el nombre "snek_types" en cualquier lugar. Por lo tanto, cualquier paquete de terceros podrá crear un punto de entrada "snek_types" en su setup.py para cargarlo con nuestro script.

Hablamos sobre snek_types con nuestros colegas de Snake Solutions LLC, e inmediatamente comenzaron a crear la serpiente de sus sueños. Así es como surgió su paquete cute_snek.py :

 cute_snek = r""" /^\/^\ _|__| O| \/ /~ \_/ \ \____|__________/ \ \_______ \ `\ \ \ | | \ / / \ / / \ / / \ \ / / \ \ / / _----_ \ \ / / _-~ ~-_ | | ( ( _-~ _--_ ~-_ _/ | \ ~-____-~ _-~ ~-_ ~-_-~ / ~-_ _-~ ~-_ _-~ ~--______-~ ~-___-~ """ 

Y así es como implementaron su setup.py para que nuestro snek pueda cargar su serpiente:

 from setuptools import setup setup( name='cute_snek', entry_points={ 'snek_types': [ 'cute = cute_snek:cute_snek', ], } ) 

Registraron la variable cute_snek en el módulo cute_snek con el nombre cute . Luego, instalan los paquetes snek y cute_snek :

 $ cd cute_snek && python setup.py develop running develop running egg_info writing cute_snek.egg-info\PKG-INFO writing dependency_links to cute_snek.egg-info\dependency_links.txt writing entry points to cute_snek.egg-info\entry_points.txt writing top-level names to cute_snek.egg-info\top_level.txt reading manifest file 'cute_snek.egg-info\SOURCES.txt' writing manifest file 'cute_snek.egg-info\SOURCES.txt' running build_ext Creating c:\program files (x86)\py36-32\lib\site-packages\cute-snek.egg-link (link to .) cute-snek 0.0.0 is already the active version in easy-install.pth Installed c:\users\rachum\cute_snek Processing dependencies for cute-snek==0.0.0 Finished processing dependencies for cute-snek==0.0.0 

Ahora, al ejecutar snek , pueden sacar su serpiente del paquete cute_snek cargándola dinámicamente en el punto de entrada:

 $ snek --type cute /^\/^\ _|__| O| \/ /~ \_/ \ \____|__________/ \ \_______ \ `\ \ \ | | \ / / \ / / \ / / \ \ / / \ \ / / _----_ \ \ / / _-~ ~-_ | | ( ( _-~ _--_ ~-_ _/ | \ ~-____-~ _-~ ~-_ ~-_-~ / ~-_ _-~ ~-_ _-~ ~--______-~ ~-___-~ 

Serpiente 2.0


Si bien toda la atención de la alta dirección se dirige al desmontaje con la inspección fiscal y el servicio antimonopolio, el departamento de desarrollo finalmente puede encontrar algo de tiempo para refactorizar el código.

El arquitecto jefe del sistema se dio cuenta de que si las serpientes de terceros se pueden descargar como complementos, las serpientes incorporadas también se pueden descargar.

Eliminamos el procesamiento especial de las serpientes incorporadas:

 --- a/snek.py +++ b/snek.py @@ -31,10 +31,7 @@ fancy_snek = """\ """ def get_sneks(): - sneks = { - 'normal': normal_snek, - 'fancy': fancy_snek, - } + sneks = {} for entry_point in pkg_resources.iter_entry_points('snek_types'): sneks[entry_point.name] = entry_point.load() return sneks 

Y a cambio, registraremos puntos de entrada universales para ellos:

 --- a/setup.py +++ b/setup.py @@ -6,5 +6,9 @@ setup( 'console_scripts': [ 'snek = snek:main', ], + 'snek_types': [ + 'normal = snek:normal_snek', + 'fancy = snek:fancy_snek', + ], }, ) 

Vuelva a instalar la serpiente modificada:

 $ python setup.py develop running develop running egg_info writing snek.egg-info\PKG-INFO writing dependency_links to snek.egg-info\dependency_links.txt writing entry points to snek.egg-info\entry_points.txt writing top-level names to snek.egg-info\top_level.txt reading manifest file 'snek.egg-info\SOURCES.txt' writing manifest file 'snek.egg-info\SOURCES.txt' running build_ext Creating c:\program files (x86)\py36-32\lib\site-packages\snek.egg-link (link to .) snek 0.0.0 is already the active version in easy-install.pth Installing snek-script.py script to C:\Program Files (x86)\Py36-32\Scripts Installing snek.exe script to C:\Program Files (x86)\Py36-32\Scripts Installing snek.exe.manifest script to C:\Program Files (x86)\Py36-32\Scripts Installed c:\users\rachum\notebooks Processing dependencies for snek==0.0.0 Finished processing dependencies for snek==0.0.0 

Comprueba el resultado:

 $ snek --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` $ snek --type fancy _,..,,,_ '``````^~"-,_`"-,_ .-~c~-. `~:. ^-. `~~~-.c ; `:. `-, _.-~~^^~:. `. ; _,--~~~~-._ `:. ~. .~ `. .` ;' .:` `: `:. ` _.:-,. `. .' .: :' _.-~^~-. `. `..' .: `. ' : .' _:' .-' `. :. .: .'`. : ; : `-' .:' `. `^~~^` .:. `. ; ; `-.__,-~ ~-. ,' ': '.__.` :' ~--..--' ':. .:' ':..___.:' $ snek --type cute /^\/^\ _|__| O| \/ /~ \_/ \ \____|__________/ \ \_______ \ `\ \ \ | | \ / / \ / / \ / / \ \ / / \ \ / / _----_ \ \ / / _-~ ~-_ | | ( ( _-~ _--_ ~-_ _/ | \ ~-____-~ _-~ ~-_ ~-_-~ / ~-_ _-~ ~-_ _-~ ~--______-~ ~-___-~ 



Eso es todo ¡Ahora ya sabe cómo usar los puntos de entrada en Python!

Source: https://habr.com/ru/post/479570/


All Articles