【问题标题】:Create an import statement using variable "interpolation"使用变量“interpolation”创建导入语句
【发布时间】:2012-07-09 23:19:46
【问题描述】:

我有一长串可能需要导入的文件。我只需要其中的 1 个,而且它们都有相同的界面。 (选择支付网关来处理支付)

假设我有一个代表所有网关文件名称的字典。

gateways = {
   '1' : 'authorize',
   '2' : 'paysimple',
   '3' : 'braintreepayments',
   '4' : 'etc',
}

我根据数据库中的信息知道这本词典的键。因此,如果我收到网关值为 1 的支付流程请求,我知道它需要由 Authorize.net 处理。 A 2 将由 Pay Simple 处理。等等。

我希望能够创建一个使用我知道的信息构建的导入语句,而不是一个可怕的 elif 语句列表。

考虑下面的简单方法:

# For the purposes of this example assume payment_gateway is defined
# elsewhere and represents the key to the dictionary
gateway_file = gateways.get(payment_gateway)

import_str = "from gateway_interface.%s import process" % gateway_file
gogo(import_str)

gogo 是一种使 import 语句实际导入的方法。

这样的事情可能吗?

【问题讨论】:

  • 您确定您的流程只处理一笔付款然后退出吗?这听起来很不寻常。
  • 我不确定这有什么不寻常之处。如果您进行在线购物并要求结帐,为什么要使用多个网关处理交易?
  • 您一次只能使用一个,但通常在线购物将由一个长时间运行的进程处理,该进程在其生命周期内处理许多请求。
  • @Ned Batchelder 你能详细说明一下这个想法吗?我不确定我是否理解为什么让进程继续运行会是有利的。我们正在使用 Django 并发布到一个视图,这将产生这个过程。你有更好的方法来处理这个问题吗?

标签: python import string-interpolation


【解决方案1】:

最简单

process = __import__('gateway_interface.'+gateway_file,fromlist=['foo']).process

编辑:fromlist 中的 'foo' 可以是任何东西,只要 fromlist 不是空列表即可。 Why does Python's __import__ require fromlist? 中解释了那一点点奇怪。

我还必须进行编辑,因为在我的第一篇文章中 __import__ 没有像 Python's __import__ doesn't work as expected 中进一步描述的那样按预期工作。

如果你有 python 2.7

import importlib
process = importlib.import_module('gateway_interface.'+gateway_file).process

使用 package_tools 很酷(例如from pkg_resources import iter_entry_points

即使它们位于不在 gateway_interface 下的奇数包中,也可以为您提供找到正确函数的解决方案。如果它们都在一个地方,并且您不需要那种矫枉过正的风格,那么...是的,只需__import__

【讨论】:

  • 这不太适合我,我不确定我做错了什么。我收到以下错误:'module' object has no attribute 'process'
  • 我会测试,不确定您尝试了两种方法中的哪一种。 gateway_file 子目录中有__init__.py 吗?
  • 一切都在同一个模块gateway_interface中。我需要导入的文件有一个名为process 的类,我需要对其进行实例化。是的,gateway_interface__init__.py
  • 我修复了 getattr 版本。我还将 fromlist 关键字添加到__import__。我将在答案中发布编辑以解释为什么需要这样做,但这是包与模块导入之间的区别。当前的编辑应该可以工作。
  • 是的,太棒了!实际上,我在 2.7 之前的版本和 importlib 方式都尝试过。我喜欢后者。 :)
【解决方案2】:

看看imp 模块,它允许您访问import 语句的内部,或者__import__ 方法本身——这其中任何一个都应该可以让您实现您所描述的我的想法。

【讨论】:

    【解决方案3】:

    内置的__import__ 方法应该可以工作:

    process = __import__(gateways.get(payment_gateway)).process
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 2011-04-05
      • 2020-08-02
      • 1970-01-01
      相关资源
      最近更新 更多