【问题标题】:How to pass a string as an object to getattr python如何将字符串作为对象传递给getattr python
【发布时间】:2017-10-20 05:42:05
【问题描述】:

我有许多函数需要从各种导入的文件中调用。

函数的格式如下:

a.foo
b.foo2
a.bar.foo4
a.c.d.foo5

它们作为原始字符串传递给我的脚本。

我正在寻找一种干净的方式来运行这些,带参数,并获取返回值

现在我有一个混乱的系统来拆分字符串,然后将它们提供给正确的 getattr 调用,但这感觉有点笨拙并且非常不可扩展。有没有办法可以将 getattr 的对象部分作为字符串传递?还是其他方式?

import a, b, a.bar, a.c.d

if "." in raw_script:
    split_script = raw_script.split(".")
    if 'a' in raw_script:
        if 'a.bar' in raw_script:
            out = getattr(a.bar, split_script[-1])(args)
        if 'a.c.d' in raw_script:
            out = getattr(a.c.d, split_script[-1])(args)
        else:
            out = getattr(a, split_script[-1])(args)
    elif 'b' in raw_script:
        out = getattr(b, split_script[-1])(args)

【问题讨论】:

    标签: python python-3.x getattr


    【解决方案1】:

    试试这个:

    def lookup(path):
        obj = globals()
        for element in path.split('.'):
            try:
                obj = obj[element]
            except KeyError:
                obj = getattr(obj, element)
        return obj
    

    请注意,这将处理以任何全局名称开头的路径,而不仅仅是您的 ab 导入的模块。如果对向函数提供不受信任的输入存在任何可能的问题,您应该从包含允许起点的 dict 开始,而不是整个 globals dict。

    【讨论】:

      【解决方案2】:

      很难从您的问题中看出,但听起来您有一个以my-tool <function> [options] 运行的命令行工具。你可以像这样使用importlib,避免大多数getattr调用:

      import importlib
      
      def run_function(name, args):
          module, function = name.rsplit('.', 1)
          module = importlib.import_module(module)
          function = getattr(module, function)
          function(*args)
      
      if __name__ == '__main__':
          # Elided: retrieve function name and args from command line
          run_function(name, args)
      

      【讨论】:

        猜你喜欢
        • 2013-01-21
        • 1970-01-01
        • 2019-11-16
        • 2011-03-17
        • 2020-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-08
        相关资源
        最近更新 更多