检查 class 名称(字符串)是否用于 Python 中的某些 class
Check if class name (a string) is used for some class in Python
如何获得在给定名称下(在当前范围内)可用的确切 class 变量?我想写一个这样的函数:
from my_module import ClassA # A subclass of my_other_module.BenevolentClass
from my_other_module import my_function
a = 'ClassA'
cls_var = my_function(a)
o = cls_var()
这样我就可以向 my_function 提供任何字符串,只要该字符串在调用者的命名空间中作为 class 名称可用,它就会产生正确的 class much就像我将字符串直接复制粘贴到代码中一样。原因是我需要为复杂的对象创建例程提供 class 名称,但尽可能避免使用 eval
。我目前的实现是这样的:
def my_function(name):
if name in globals():
c = globals()[name]
# Actually a complex class whitelist
if issubclass(c, BenevolentClass):
return c
else:
raise ValueError(f'Potentially malicious class {name}')
但这显然从 my_other_module 生成了 globals(),这不是我想要的。我想要在调用 my_function
的确切代码行中可用的所有 classes(它可能在完全不同的模块中,从另一个模块调用)。
您可以将全局字典传递给 my_function。
def my_function(name, g):
if name in g:
...
cls_var = my_function(a, globals())
我想我找到了解决办法。不确定它是否完美,所以我宁愿在接受我自己的回答之前先听听一些评论。
import inspect
def my_function(name):
for frame in inspect.getouterframes(inspect.currentframe()):
c = None
if name in frame.frame.f_globals:
c = frame.frame.f_globals[name]
break
if c and issubclass(c, BenevolentClass):
return c
else:
raise ValueError(f'Potentially malicious class {name}')
据我了解,inspect.getouterframes
沿着调用堆栈向外走,我可以检查每一步的全局变量以查看可用的内容。 frame.f_globals
中既没有局部变量也没有内置函数,因此它似乎没有太大的注入恶意数据的潜力。
如何获得在给定名称下(在当前范围内)可用的确切 class 变量?我想写一个这样的函数:
from my_module import ClassA # A subclass of my_other_module.BenevolentClass
from my_other_module import my_function
a = 'ClassA'
cls_var = my_function(a)
o = cls_var()
这样我就可以向 my_function 提供任何字符串,只要该字符串在调用者的命名空间中作为 class 名称可用,它就会产生正确的 class much就像我将字符串直接复制粘贴到代码中一样。原因是我需要为复杂的对象创建例程提供 class 名称,但尽可能避免使用 eval
。我目前的实现是这样的:
def my_function(name):
if name in globals():
c = globals()[name]
# Actually a complex class whitelist
if issubclass(c, BenevolentClass):
return c
else:
raise ValueError(f'Potentially malicious class {name}')
但这显然从 my_other_module 生成了 globals(),这不是我想要的。我想要在调用 my_function
的确切代码行中可用的所有 classes(它可能在完全不同的模块中,从另一个模块调用)。
您可以将全局字典传递给 my_function。
def my_function(name, g):
if name in g:
...
cls_var = my_function(a, globals())
我想我找到了解决办法。不确定它是否完美,所以我宁愿在接受我自己的回答之前先听听一些评论。
import inspect
def my_function(name):
for frame in inspect.getouterframes(inspect.currentframe()):
c = None
if name in frame.frame.f_globals:
c = frame.frame.f_globals[name]
break
if c and issubclass(c, BenevolentClass):
return c
else:
raise ValueError(f'Potentially malicious class {name}')
据我了解,inspect.getouterframes
沿着调用堆栈向外走,我可以检查每一步的全局变量以查看可用的内容。 frame.f_globals
中既没有局部变量也没有内置函数,因此它似乎没有太大的注入恶意数据的潜力。