我在一个模块中有以下设置:
class A(object):
# stuff
class B(object):
# stuff
现在我想做的是,A
在B
. 我怎样才能避免这个globals
功能?
我在一个模块中有以下设置:
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
。
让我看看我是否理解正确:
你有一个看起来像的设置文件
...
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 类”是什么意思,但通常有三种主要方法,具体取决于您实际想要做什么。
__init__