如何别名对象的所有方法?

问题描述 投票:5回答:4

我正在创建一个脚本,实际上是其他用户编写代码的环境。

我已经在类中声明了几个方法并实例化了一个对象,因此用户可以将这些方法用作简单的解释器函数,如下所示:

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下自动显示?

python python-3.x object interpreter interactive
4个回答
4
投票

你控制传递给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)轻松地包含它们。


1
投票

我不知道你打算用这些函数做什么,但如果它们不是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中的所有自定义函数放到全局范围内。


0
投票

你基本上想要做两件事:

  1. 获取类实例的方法列表
  2. 动态地向本地范围添加功能

前者可以使用标准库中的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())

0
投票

这是类似于@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
© www.soinside.com 2019 - 2024. All rights reserved.