3

我在一个模块中有以下设置:

class A(object):
    # stuff

class B(object):
    # stuff

现在我想做的是,AB. 我怎样才能避免这个globals功能?

4

3 回答 3

7

为什么不直接使用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

于 2012-05-19T12:05:14.987 回答
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字典;换句话说,假设最终用户知道您要使用的类名。这不好。

于 2012-05-19T12:42:53.003 回答
2

我不清楚“按名称访问 A 类”是什么意思,但通常有三种主要方法,具体取决于您实际想要做什么。

  1. 您在 B 类中创建 A 类的实例__init__
  2. 您从 B 类中的 A 类继承
  3. @ThiefMaster 发布的内容。
于 2012-05-19T12:07:13.930 回答