Unable to dynamically create classes with local scope within a function but works at the top level.
How to create classes dynamically at the correct namespace scope.
我正在尝试动态创建添加到调用者命名空间的类。在
这样我就可以做下面的事情了。在
import creator
creator.make('SomeClass')
print "SomeClass :", SomeClass
当在顶层添加动态类时,这一点是可以实现的,但是当试图在一个函数中进行同样的操作时,这样创建的类只有局部作用域,它不起作用。在
我看到有一个hack当放在函数内部时,它会起作用,但它会消失。在
下面的代码显示了问题,很明显,creator.py
要比显示的更多。在
# example.py
import creator
print "WILL __main__ - locals :", locals().keys()
creator.make('SomeClass')
print "DID __main__ - locals :", locals().keys()
print "SomeClass :", SomeClass
print "-" * 80
def closed():
# This hack helps
# https://stackoverflow.com/a/1549221/1481060
# exec ''
class ClosedClass: pass
print "WILL closed() - locals :", locals().keys()
creator.make('AnotherClass')
print "DID closed() - locals :", locals().keys()
# NOT EXPECTED
try: print AnotherClass
except NameError, ex: print "OUCH:", ex
closed()
输出:
WILL __main__ - locals : ['creator', '__builtins__', '__file__', '__package__', '__name__', '__doc__']
WILL make() - callers locals : ['creator', '__builtins__', '__file__', '__package__', '__name__', '__doc__']
DID make() - callers locals : ['creator', '__builtins__', 'SomeClass', '__file__', '__package__', '__name__', '__doc__']
DID __main__ - locals : ['creator', '__builtins__', 'SomeClass', '__file__', '__package__', '__name__', '__doc__']
SomeClass : <class 'creator.SomeClass'>
--------------------------------------------------------------------------------
WILL closed() - locals : ['ClosedClass']
WILL make() - callers locals : ['ClosedClass']
DID make() - callers locals : ['ClosedClass', 'AnotherClass']
DID closed() - locals : ['ClosedClass', 'AnotherClass']
OUCH: global name 'AnotherClass' is not defined
我当然不想要OUCH:..
。在
看看closed
中的locals()
你会认为它应该可以工作,但是正如hack中提到的,Python编译器正在优化局部变量,而没有引入新的动态编译器。在
如果我取消了exec ''
行的注释,那么它就可以工作了。在
我可以用全局范围创建这些类,但我正在努力保持我的名称空间干净。在
我当然可以做AnotherClass = creator.make('AnotherClass')
,但我试着让它保持干燥。在
有没有一种方法可以让它在没有exec ''
黑客的情况下工作?在
或者这是一个使它们全球化的案例?在
否。访问局部变量的唯一方法是通过^{} 或{},在这两种情况下,文档都明确指出,不能保证对
dict
返回的修改会影响局部变量,因此:没有可靠的方法来做到这一点。在如果你想静态地修改局部变量那么也许你可以修改与函数相关联的代码对象来提供更多的局部变量,但这可能是不可能的,也可能很难可靠地实现,我认为没有理由这样做。在
相关问题 更多 >
编程相关推荐