繁体   English   中英

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

[英]Python: Accessing another class of current module by name

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

class A(object):
    # stuff

class B(object):
    # stuff

现在我想做的是,在B内部按名称创建一个A类实例(我只是将类名作为字符串)。 我怎么能避免globals函数呢?

为什么不用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更快。

让我看看我是否理解你:

  • 你有一个类似的设置文件

     ... 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字典; 换句话说,假设最终用户知道您要使用的类名。 那不好。

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

  1. 你在类B的__init__创建了一个A类实例
  2. 您继承自B类中的A类
  3. @ThiefMaster发布了什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM