2012-05-19 46 views
3

访问另一个类当前模块的我已经在一个模块中的以下设置:的Python:按名称

class A(object): 
    # stuff 

class B(object): 
    # stuff 

现在我想要做的是,通过名字创建A类的一个实例(我只是有类名称作为字符串)在B之内。我该如何避免globals函数?

+0

你是什么意思“按内部名称访问A类”? – DonCallisto

+0

我有类名作为字符串。 – Martin

+0

而且......用那个字符串你要做什么? – DonCallisto

回答

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去。

+0

但是会更快?我认为,globals并不是真正的高性能 – Martin

+0

你为什么这么认为?这种极可能忽略不计的性能差异真的很重要吗? – ThiefMaster

+0

取决于性能差异。如果它可以忽略不计,'globals'可以。但我并不是Python中的_that_ pro;) – Martin

2

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

  1. 创建内部类A的实例B类的__init__
  2. 你从A类继承B类
  3. 贴什么@ThiefMaster。
+0

继承对我来说并不是一个好的方法,也可以通过硬编码访问。 – Martin

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

+0

好的答案!该设置对用户不可见,这是一个项目设置。但在这方面,我不确定是否可以在那时导入课程。 – Martin