草庐IT

python - python/setuptools 入口点(扩展)在其他语言/应用程序中的替代实现

coder 2023-05-21 原文

虽然这个问题有一个 python 后端,但问题是 不是 与 python 本身相关,而是关于扩展机制以及如何注册/查找插件。

在 Python 中,入口点的概念是由 setuptools 引入的,并且与已安装的 Python 发行版(在其他打包系统中称为包)的元数据相关联。

据我了解,入口点提供的功能之一是允许应用程序定义其他人可以放置东西的地方,因此任何想要使用入口点的应用程序都可以在那里获得已注册类/函数的列表。让我们举个例子:

  • Foo 定义入口点“entrypoint1”并查找以该名称注册的插件。
  • Bar 在“entrypoint1”入口点注册一个可调用( Bar.callable )。
  • 任何 python 脚本都可以列出 Bar.callable作为“entrypoint1”的注册可调用对象之一。

  • 使用 setuptools,应用程序在安装时注册入口点,并将信息存储在与打包相关的元数据中,称为 .egginfo(通常包含有关分发名称、其依赖项的信息以及一些有关打包的更多元数据)。

    我觉得包装元数据不是存储此类信息的正确位置,因为我不明白为什么这些信息与包装相关联。

    我很想知道其他语言中的此类入口点/扩展/插件功能,尤其是如果该概念与元数据和包装相关联。所以问题是……

    你有我应该看的例子吗?你能解释一下为什么设计选择是这样的吗?

    你能看到处理这个问题的不同方法吗?你知道这个问题是如何在不同的工具中解决的吗?当前 python 实现相对于其他实现的缺点和优点是什么?

    到目前为止我发现了什么

    我在不同的项目中发现了一种创建和分发“插件”的方法,它特别关注“我们如何制作插件”。

    例如,libpeas (gobject 插件框架)定义了一组通过指定插件来扩展默认行为的方法。虽然这很有趣,但我只是对它的“注册和查找”(并最终加载)部分感兴趣。

    以下是我目前的一些发现:

    Libpeas 定义 its own metadata file (*.plugin),它存储有关可调用类型的信息(可能有不同语言的不同插件)。这里的主要信息是要加载的模块的名称。

    Maven有a design document包含有关如何在那里管理东西的信息。 Maven 管理插件及其依赖项和元数据,因此它看起来是一个有趣的地方 how they implemented things .

    正如他们的文档中所指定的,maven plugins are using annotations ( @goal ) 在类上,然后用于查找使用特定 @goal 注册的所有插件.虽然这种方法在静态语言中是可能的,但它在解释性语言中是不可能的,因为我们只知道在一个给定的时间点所有可能的类/可调用对象是什么,这可能会发生变化。

    Mercurial 使用 a central configuration file ( ~/.hgrc ),包含插件名称到可以找到的路径的映射。

    更多想法

    虽然这不是这个问题的答案,但值得注意的是 setuptools 入口点是如何实现的,以及它们在性能方面如何与善变的入口点进行比较。

    当您使用 setuptools 请求特定入口点时,all the metadata are read at run time and a list is built that way .这意味着如果您的路径上有很多 python 发行版,则此阅读可能需要一些时间。另一方面,Mercurial 将此信息硬编码到单个文件中,这意味着您必须在那里指定可调用对象的完整路径,然后注册的可调用对象不会被“发现”,而是直接从配置文件中“读取”。这允许对应该可用和不应该可用的内容进行更细粒度的配置,并且看起来更快。

    另一方面,由于可以在运行时更改 python 路径,这意味着必须根据路径检查以这种方式提供的可调用对象,以便知道是否在所有情况下都应该返回它们。

    为什么入口点目前与包装相关联

    理解为什么入口点与 setuptools 中的包装相关联也很有趣。主要原因是python发行版可以在安装时将自身的一部分注册为扩展入口点似乎很有用:然后安装意味着也注册入口点:不需要额外的注册步骤。

    虽然这在大多数情况下都相当有效(当实际安装 python 发行版时),但在未安装或未打包时则不然。换句话说,据我所知,如果没有 .egg-info 文件,您就无法在运行时注册入口点。

    最佳答案

    作为可能的想法之一,您可以查看 OSGi概念,用于Eclipse的插件系统管理.对于您的特定案例,这可能有点矫枉过正,但绝对是灵感的来源。

    关于python - python/setuptools 入口点(扩展)在其他语言/应用程序中的替代实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7051577/

    有关python - python/setuptools 入口点(扩展)在其他语言/应用程序中的替代实现的更多相关文章

    1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

      总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

    2. ruby - 其他文件中的 Rake 任务 - 2

      我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

    3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

      作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

    4. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

      关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

    5. ruby-on-rails - Rails 3 中的多个路由文件 - 2

      Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

    6. ruby - 将差异补丁应用于字符串/文件 - 2

      对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

    7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

      我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

    8. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

      我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

    9. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

      我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

    10. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

      我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

    随机推荐