Python:按名称访问另一类当前模块

时间:2012-05-19 12:01:58

标签: python

我在一个模块中进行了以下设置:

class A(object):
    # stuff

class B(object):
    # stuff

现在我要做的是,在A内部按名称创建类B的实例(我只是将类名作为字符串)。如何避免globals功能?

3 个答案:

答案 0 :(得分:6)

为什么不使用A?或者你只有一个字符串'A'?如果是,globals()['A']是可行的方法。替代方案是getattr(sys.modules[__name__], 'A'),但显然globals()更合适。

>>> dis.dis(lambda: getattr(sys.modules[__name__], 'Foo'))
  1           0 LOAD_GLOBAL              0 (getattr)
              3 LOAD_GLOBAL              1 (sys)
              6 LOAD_ATTR                2 (modules)
              9 LOAD_GLOBAL              3 (__name__)
             12 BINARY_SUBSCR
             13 LOAD_CONST               1 ('Foo')
             16 CALL_FUNCTION            2
             19 RETURN_VALUE

>>> dis.dis(lambda: globals()['Foo'])
  1           0 LOAD_GLOBAL              0 (globals)
              3 CALL_FUNCTION            0
              6 LOAD_CONST               1 ('Foo')
              9 BINARY_SUBSCR
             10 RETURN_VALUE

>>> dis.dis(lambda: Foo)
  1           0 LOAD_GLOBAL              0 (Foo)
              3 RETURN_VALUE

因此,只需查看用于访问Foo的各种方式的说明,使用globals()最有可能比通过sys.modules更快。

答案 1 :(得分:3)

让我看看我是否理解你:

  • 您的设置文件类似于

    ...
    connection-type: FooConnection
    ...
    
  • 你有一堆课程

    class FooConnection(Connection): ...
    class BarConnection(Connection): ...
    class BazConnection(Connection): ...
    
  • 您希望将"FooConnection"从设置文件映射到 FooConnection


如果是这样,我会这样做:

  • connection-type: Foo
    

    在设置文件中,或其他一些不依赖于类名称的人类可读名称。

  • 编写从人类可读名称到实现的映射:

    implementations = {
        "Foo": FooConnection,
        "Bar": BarConnection,
        "Baz": BazConnection
    }
    

    如果您想要更改此映射,则可以更改此映射。你如何实现这些类。这也让你有同义词。

  • 在实现词典的设置文件中查找值,以获得所需的课程。


事实上,你已经这样做了。只是,您没有明确写下字符串到类的映射,而是使用globals字典;换句话说,假设最终用户知道您要使用的类名。那不好。

答案 2 :(得分:2)

我不清楚你的意思是"通过名字"访问A级,但通常有三种主要方法,具体取决于你真正想做的事情。

  1. 您在班级B' s __init__
  2. 中创建了A类的实例
  3. 您继承自B类中的A类
  4. @ThiefMaster发布的内容。