我正在创建一个脚本,实际上是其他用户编写代码的环境。
我已经在类中声明了几个方法并实例化了一个对象,因此用户可以将这些方法用作简单的解释器函数,如下所示:
from code import interact
class framework:
def method1(self, arg1):
# code for method1
def method2(self, arg2):
# code for method2
def main():
fw = framework()
# Aliases
method1 = fw.method1
method2 = fw.method2
interact(local=locals())
由于我不希望用户使用fw.method1(arg)
调用方法,因此我设置了别名。问题是,由于框架类正在开发中,我必须继续使用我创建的方法的新别名更新主脚本。
是否有一种简单的方法可以摆脱调用中的“fw.
”部分并让类框架下的所有方法在main下自动显示?
你控制传递给interact
的字典,所以把你想要的东西放进去,而不用担心main
中的局部变量:
d={}
for n in vars(framework):
if n.startswith('_'): continue # probably
x=getattr(fw,n)
if callable(x): d[n]=x
interact(local=d)
这适用于常规,静态和类方法。它不会看到实例属性(除非它们隐藏了类属性)或继承的方法。
前者仅在实例将函数存储为属性时才起作用(在这种情况下,您可能希望或可能不希望它们可用)。后者很方便,因为它省略了object
;如果有其他基类,可以通过搜索framework.__mro__
(并且仍然省略object
)轻松地包含它们。
我不知道你打算用这些函数做什么,但如果它们不是static
,那么它不可能在课外工作:
fs = [func for func in dir(c) if callable(getattr(c, func)) and not func.startswith("__")]
for func in fs:
globals()[func] = getattr(c, func)
这会将类c
中的所有自定义函数放到全局范围内。
你基本上想要做两件事:
前者可以使用标准库中的inspect
模块实现,后者使用vars
实现。
请尝试以下方法:
import inspect
from code import interact
class framework:
def method1(self, arg1):
# code for method1
def method2(self, arg2):
# code for method2
def main():
fw = framework()
# get the methods of fw and update vars().
# getmembers returns a list of two-tuples with (<Name>, <function>)
methods = inspect.getmembers(fw, predicate=inspect.ismethod)
vars().update({method[0]: method[1] for method in methods})
interact(local=locals())
这是类似于@Davis Herring的回答,充实和重新包装:
#from code import interact
def interact(local):
local['method1'](42)
local['method2']('foobar')
class Framework:
def method1(self, arg1):
print('Framework.method1({!r}) called'.format(arg1))
def method2(self, arg2):
print('Framework.method2({!r}) called'.format(arg2))
def get_callables(obj):
return {name: getattr(obj, name) for name in vars(obj.__class__)
if callable(getattr(obj, name))}
def main():
fw = Framework()
# # Aliases
# method1 = fw.method1
# method2 = fw.method2
interact(local=get_callables(fw))
if __name__ == '__main__':
main()
输出:
Framework.method1(42) called
Framework.method2('foobar') called