在这篇文章中,我将解释关于Python的入口点。大多数人都知道入口点是您在setup.py文件中放入的小片段,以使您的程序包可作为命令行上的脚本使用,但是它们可用于更多用途。我将向您展示如何将入口点用作模块化插件体系结构。如果您想让其他人编写在运行时与现有Python程序包交互或添加功能的Python程序包,这将非常有用。
!! WARNING: 前方高冷笑话 !!
Snek,Inc.
恭喜你!您刚刚被任命为“ Snek半导体和软件有限公司”的首席执行官。显然,您担任CEO的第一份工作是指示您的研发部门尽快开发出精美的原型。因此,他们开始工作,写作snek.py:
ascii_snek = """\ --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` """ def main(): print(ascii_snek) if __name__ == '__main__': main()
他们的原型在公司演示日被展示出来,并且有效!
$ python snek.py --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'`
SaaS-Snek即服务
不幸的是,客户对Python并不了解(除了snek)。他们希望可以轻松地从命令行(shell)中的任何路径访问snek,而不必担心该Python事情或寻找snek.py。因此,研发部门的负责人通宵工作,并提出了一种打包snek的方法,该方法可以在安装后自动创建控制台脚本。为Python软件包创建分发时,需要具有一个setup.py包含软件包名称,依赖项等的文件。它也可以用于注册入口点,如下所示:
from setuptools import setup setup( name='snek', entry_points={ 'console_scripts': [ 'snek = snek:main', ], } )
console_scripts 意思是,这是一种特殊的切入点。在安装软件包时 setuptools
读取其内容,"<console script name> = <python object path>"并创建一个适当的脚本。现在,他们正在从源代码安装它:
$ 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
在备受赞誉的SnekCon会议上的主题演讲(门票已提前六个月售罄)中,您登台演讲,并向全世界展示:
$ snek --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'`
贪吃的人
每个人都喜欢偷偷摸摸。“ Snek半导体和软件股份有限公司”进行了首次公开募股,市值超过600亿美元。赶时髦的人要求发疯的版本。您的研发团队将提供:
"""Print an ASCII Snek. Usage: 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()
他们增加了一些幻想。现在,赶时髦的人很高兴。
$ snek --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` $ snek --type fancy _,..,,,_ '``````^~"-,_`"-,_ .-~c~-. `~:. ^-. `~~~-.c ; `:. `-, _.-~~^^~:. `. ; _,--~~~~-._ `:. ~. .~ `. .` ;' .:` `: `:. ` _.:-,. `. .' .: :' _.-~^~-. `. `..' .: `. ' : .' _:' .-' `. :. .: .'`. : ; : `-' .:' `. `^~~^` .:. `. ; ; `-.__,-~ ~-. ,' ': '.__.` :' ~--..--' ':. .:'
斯尼克国际社区
全世界数以百万计的人正在使用snek。即使收购了Google,“ Snek半导体和软件有限公司”也无法跟上对Snek越来越多版本的需求增长!专业客户要求可定制版本的snek!他们想在snek基础架构之上创建自己的snek。研发更卖力地开始工作。
"""Print an ASCII Snek. Usage: 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()
他们添加了可自定义小工具的基础结构。每当snek运行时,它都会查找使用称为的入口点注册的其他小东西snek_types。每个snek是在类型名称下注册的字符串。该名称可以与控制台脚本一起使用,以动态打印自定义修饰。
特别是,魔术发生在中get_sneks。对的调用会pkg_resources.iter_entry_points('snek_types')
遍历以名称注册的所有入口点"snek_types"。因此,外部包可以定义称为入口点"snek_types"在他们的 setup.py,并snek在运行时将动态加载。
“ Snek Pro解决方案和咨询服务”的家伙们知道了有关"snek_types"切入点的事,并已开始研究比您想象中要好得多的snek版本。可爱的snek。他们的cute_snek.py用很少的代码创建了一个简单的代码:
cute_snek = r""" /^\/^\ _|__| O| \/ /~ \_/ \ \____|__________/ \ \_______ \ `\ \ \ | | \ / / \ / / \ / / \ \ / / \ \ / / _----_ \ \ / / _-~ ~-_ | | ( ( _-~ _--_ ~-_ _/ | \ ~-____-~ _-~ ~-_ ~-_-~ / ~-_ _-~ ~-_ _-~ ~--______-~ ~-___-~ """
他们在打包 cute_snek,但也需要让他们snek知道如何找到cute snek。
from setuptools import setup setup( name='cute_snek', entry_points={ 'snek_types': [ 'cute = cute_snek:cute_snek', ], } )
他们以该名称cute_snek在cute_snek模块中注册了该变量cute。现在,他们同时安装snek和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
现在,运行snek,它们可以产生一个可爱的snek,该snek从cute_snek包中动态加载:
$ snek --type cute /^\/^\ _|__| O| \/ /~ \_/ \ \____|__________/ \ \_______ \ `\ \ \ | | \ / / \ / / \ / / \ \ / / \ \ / / _----_ \ \ / / _-~ ~-_ | | ( ( _-~ _--_ ~-_ _/ | \ ~-____-~ _-~ ~-_ ~-_-~ / ~-_ _-~ ~-_ _-~ ~--______-~ ~-___-~
Snek基础设施大修
您的副总裁研发部有要求。他想停止开发一段时间,而他的工程师则清理snek基础结构以获取更好的代码库。公开指控称您在snek交易市场进行内幕交易时挪用了snek的行为,这让您太分心了,因此您只好同意了这样做。
研发工程师得出的结论是,如果可以动态加载某些snek,则可以动态加载所有snek!甚至是内置的snek!他们取消了对现有snek的特殊对待:
--- 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
而且,可以像其他任何方式一样注册它们:
--- 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', + ], }, )
现在,您需要重新安装snek才能使用新的入口点:
$ 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 $ snek --..,_ _,.--. `'.'. .'`__ o `;__. '.'. .'.'` '---'` ` '.`'--....--'`.' `'--....--'` $ snek --type fancy _,..,,,_ '``````^~"-,_`"-,_ .-~c~-. `~:. ^-. `~~~-.c ; `:. `-, _.-~~^^~:. `. ; _,--~~~~-._ `:. ~. .~ `. .` ;' .:` `: `:. ` _.:-,. `. .' .: :' _.-~^~-. `. `..' .: `. ' : .' _:' .-' `. :. .: .'`. : ; : `-' .:' `. `^~~^` .:. `. ; ; `-.__,-~ ~-. ,' ': '.__.` :' ~--..--' ':. .:' ':..___.:' $ snek --type cute /^\/^\ _|__| O| \/ /~ \_/ \ \____|__________/ \ \_______ \ `\ \ \ | | \ / / \ / / \ / / \ \ / / \ \ / / _----_ \ \ / / _-~ ~-_ | | ( ( _-~ _--_ ~-_ _/ | \ ~-____-~ _-~ ~-_ ~-_-~ / ~-_ _-~ ~-_ _-~ ~--______-~ ~-___-~
确实,这是一个小小的snek,一个大的snek类型(同样,您知道如何使用Python入口点)。
注:英文 snek有很多含义,注意辨别:
snek
[snek]
WHAT DOES SNEK MEAN?
Snek is internet-speak for snake. Sneks became the subject of cute, absurdist memes depicting the reptiles' inner monologue ... similar to doge.
Snek appears as what seems to be genuine misspelling in the titles of several YouTube videos between 2009 and 2011. One, uploaded under the title “Baby.snek (1).3gp,” shows a baby playing with a King Cobra snake. Or, is it a snake playing with a baby? Either way, we don’t recommend it.
By 2012, snek was being used as an intentional misspelling in memes, part of a larger culture of deliberately silly-stupid misspellings and bad grammar seen in LOLcat (e.g., I can haz moar?), doge (such wow!), and DoggoLingo (smol) memes. One from that time showed a woman apparently trying to keep a huge snake from escaping. The captions, meant to be her inner monologue, ask the snek to “stahp,” or stop.