访问另一个类当前模块的我已经在一个模块中的以下设置:的Python:按名称
class A(object):
# stuff
class B(object):
# stuff
现在我想要做的是,通过名字创建A
类的一个实例(我只是有类名称作为字符串)在B
之内。我该如何避免globals
函数?
访问另一个类当前模块的我已经在一个模块中的以下设置:的Python:按名称
class A(object):
# stuff
class B(object):
# stuff
现在我想要做的是,通过名字创建A
类的一个实例(我只是有类名称作为字符串)在B
之内。我该如何避免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
去。
但是会更快?我认为,globals并不是真正的高性能 – Martin
你为什么这么认为?这种极可能忽略不计的性能差异真的很重要吗? – ThiefMaster
取决于性能差异。如果它可以忽略不计,'globals'可以。但我并不是Python中的_that_ pro;) – Martin
我不清楚“按名称访问A类”是什么意思,但通常有三种主要方法,具体取决于您实际要做什么。
__init__
继承对我来说并不是一个好的方法,也可以通过硬编码访问。 – Martin
让我看看,如果我理解你的权利:
你有一个设置文件,看起来像
...
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
字典;换句话说,假设最终用户知道要使用的类名称。这不好。
好的答案!该设置对用户不可见,这是一个项目设置。但在这方面,我不确定是否可以在那时导入课程。 – Martin
你是什么意思“按内部名称访问A类”? – DonCallisto
我有类名作为字符串。 – Martin
而且......用那个字符串你要做什么? – DonCallisto