乐趣区

关于python:Python入口点介绍

在这篇文章中,我将解释对于 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.

see: https://www.dictionary.com/e/…

退出移动版