Muitas pessoas pensam que os pontos de entrada são instruções em
setup.py que disponibilizam o pacote para execução na linha de comando. Isso geralmente é verdade, mas os recursos dos pontos de entrada não se limitam a isso.
Abaixo, mostrarei como você pode implementar um sistema de plug-in para um pacote para que outras pessoas possam interagir com ele ou, por exemplo, expandir sua funcionalidade dinamicamente.
Cuidado : humor específico a seguir.LLC "Cobra"
Parabéns! Você acaba de ser nomeado chefe da Snake LLC. Esta é uma posição muito responsável, você não pode enfrentar a sujeira, o que significa que você precisa instruir o departamento de desenvolvimento o mais rápido possível para começar a criar um protótipo do produto. E assim, as melhores mentes da empresa começam a trabalhar no snek.py:
ascii_snek = """\ --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` """ def main(): print(ascii_snek) if __name__ == '__main__': main()
Um pouco mais tarde, em uma reunião de acionistas, você demonstra com orgulho os primeiros resultados!
$ python snek.py --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'`
Cobra como serviço
Infelizmente, o consumidor médio ainda não domina o Python e deseja executar o programa no console sem pensar no interpretador ou na localização do
snek.py. Bem, nossos melhores especialistas são os melhores que conseguiram compactar o script para que ele crie automaticamente um comando do console durante a instalação.
Para criar um pacote redistribuível, precisamos do
arquivo setup.py , que contém informações sobre dependências, licenças, etc. Além disso, você pode especificar pontos de entrada:
from setuptools import setup setup( name='snek', entry_points={ 'console_scripts': [ 'snek = snek:main', ], } )
console_scripts , como explicaram os especialistas, é um ponto de entrada especial.
O setuptools lê seus elementos como
"<script do console> = <caminho para o objeto Python>" , criando um utilitário de console para cada elemento ao instalar o pacote.
Por enquanto, vamos instalar o script a partir das fontes:
$ 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
Na conferência dedicada aos resultados do ano, você fala, demonstrando os últimos desenvolvimentos:
$ snek --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'`
Uma cobra em toda casa
A cobra conquista o mundo. A empresa realizou um IPO e foi avaliada em um recorde de US $ 60 bilhões. Os descolados exigem uma cobra nova, elegante, elegante e jovem. E se houver demanda, haverá uma 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()
Hipsters estão emocionados:
$ snek --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` $ snek --type fancy _,..,,,_ '``````^~"-,_`"-,_ .-~c~-. `~:. ^-. `~~~-.c ; `:. `-, _.-~~^^~:. `. ; _,--~~~~-._ `:. ~. .~ `. .` ;' .:` `: `:. ` _.:-,. `. .' .: :' _.-~^~-. `. `..' .: `. ' : .' _:' .-' `. :. .: .'`. : ; : `-' .:' `. `^~~^` .:. `. ; ; `-.__,-~ ~-. ,' ': '.__.` :' ~--..--' ':. .:' ':..___.:'
Cobra transnacional
Milhões de pessoas não conseguem imaginar o dia sem uma cobra. Mesmo após a aquisição do Google, os recursos do Zmeika não são suficientes para satisfazer as necessidades dos usuários em todo o mundo. Parece que chegou a hora de dar às pessoas a oportunidade de criar suas próprias cobras com base em nossa infraestrutura.
""" 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()
Agora, toda vez que o
snek é iniciado, ele procura outras cobras registradas no sistema usando o
ponto de entrada
snek_types . Cada uma dessas cobras é registrada com o nome de seu tipo, o que permite selecionar a cobra desejada, dependendo dos parâmetros do console.
Tudo o mais importante acontece dentro do
get_sneks . Chamar
pkg_resources.iter_entry_points ('snek_types') permite percorrer todos os pontos de entrada registrados com o nome
"snek_types" em qualquer lugar. Assim, qualquer pacote de terceiros poderá criar um ponto de entrada
“snek_types” em seu
setup.py para ser carregado com nosso script.
Conversamos sobre
snek_types com nossos colegas da Snake Solutions LLC e eles imediatamente começaram a criar a cobra dos seus sonhos. Foi assim que o pacote
cute_snek.py surgiu :
cute_snek = r""" /^\/^\ _|__| O| \/ /~ \_/ \ \____|__________/ \ \_______ \ `\ \ \ | | \ / / \ / / \ / / \ \ / / \ \ / / _----_ \ \ / / _-~ ~-_ | | ( ( _-~ _--_ ~-_ _/ | \ ~-____-~ _-~ ~-_ ~-_-~ / ~-_ _-~ ~-_ _-~ ~--______-~ ~-___-~ """
E aqui está como eles implementaram o
setup.py para que nosso
snek pudesse carregar sua cobra:
from setuptools import setup setup( name='cute_snek', entry_points={ 'snek_types': [ 'cute = cute_snek:cute_snek', ], } )
Eles registraram a variável
cute_snek no módulo
cute_snek sob o nome
cute . Em seguida, eles instalam os
pacotes snek e
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
Agora, executando o
snek , eles podem tirar sua cobra do pacote
cute_snek , carregando-a dinamicamente no ponto de entrada:
$ snek --type cute /^\/^\ _|__| O| \/ /~ \_/ \ \____|__________/ \ \_______ \ `\ \ \ | | \ / / \ / / \ / / \ \ / / \ \ / / _----_ \ \ / / _-~ ~-_ | | ( ( _-~ _--_ ~-_ _/ | \ ~-____-~ _-~ ~-_ ~-_-~ / ~-_ _-~ ~-_ _-~ ~--______-~ ~-___-~
Snake 2.0
Enquanto toda a atenção da alta gerência vai para a desmontagem da inspeção tributária e do serviço antimonopólio, o departamento de desenvolvimento pode finalmente encontrar algum tempo para refatorar o código.
O arquiteto-chefe do sistema percebeu que, se cobras de terceiros podem ser baixadas como plug-ins, as cobras internas também podem ser baixadas.
Removemos o processamento especial das cobras internas:
E, em troca, registraremos pontos de entrada universais para eles:
Reinstale a cobra 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
Veja o resultado:
$ snek --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` $ snek --type fancy _,..,,,_ '``````^~"-,_`"-,_ .-~c~-. `~:. ^-. `~~~-.c ; `:. `-, _.-~~^^~:. `. ; _,--~~~~-._ `:. ~. .~ `. .` ;' .:` `: `:. ` _.:-,. `. .' .: :' _.-~^~-. `. `..' .: `. ' : .' _:' .-' `. :. .: .'`. : ; : `-' .:' `. `^~~^` .:. `. ; ; `-.__,-~ ~-. ,' ': '.__.` :' ~--..--' ':. .:' ':..___.:' $ snek --type cute /^\/^\ _|__| O| \/ /~ \_/ \ \____|__________/ \ \_______ \ `\ \ \ | | \ / / \ / / \ / / \ \ / / \ \ / / _----_ \ \ / / _-~ ~-_ | | ( ( _-~ _--_ ~-_ _/ | \ ~-____-~ _-~ ~-_ ~-_-~ / ~-_ _-~ ~-_ _-~ ~--______-~ ~-___-~
Isso é tudo. Agora você sabe como usar pontos de entrada no Python!