【问题标题】:python3: getting module source code using user input (inspect .getsource)python3:使用用户输入获取模块源代码(检查.getsource)
【发布时间】:2018-07-15 17:42:03
【问题描述】:

我想做什么...
我有一个名为 'my_library.py' 的模块,其中包含一些函数或方法。
我有另一个名为 'test_library.py' 的模块,我想从 test_library 打印“my_library”模块内的一些特定函数的源代码
我知道我们可以使用....
print(inspect.getsource(my_library.add))

print(open(my_library.__file__).read())
在这里,我想将用户的函数或模块名称作为输入
示例:

    **my_library.py**
    def add(x,y):
        return x+y

    def substract(x,y):
        return x-y

    **test_library.py**
    import inspect
    import my_library
    name = "my_library.substract"
    print(inspect.getsource(name))


TypeError: module, class, method, function, traceback, frame, or code object was expected, got str
我试图将该字符串输入转换为对象、文件、类......似乎没有任何效果
有没有办法从用户那里获取输入并显示特定的功能或模块?
有什么解决问题的建议或意见吗?

提前致谢

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    假设我们有一个文件module.py

    def test_func(arg1, arg2):
        return arg1 + arg2
    

    我们可以通过获取对函数对象的引用,从另一个代码区域解析此成员以供 getsource() 使用:

    import inspect
    import sys
    import module
    
    def main():
        # what the user would input
        input_str = 'module.test_func'  
        # split user input up into individual members
        name_list = input_str.split('.')
        # extract the starting point name
        base_name = name_list[0]
        # check to make sure that name exists in the current scope and extract a reference to it
        if base_name in locals():
            base_obj = locals()[base_name]
        elif base_name in globals():
            base_obj = globals()[base_name]
        else:
            print('base name {} is unknown'.format(base_name))
            return 1
        # iteratively step through the attribute chain
        containing_object = base_obj
        for name in name_list[1:]:
            try:
                containing_object = getattr(containing_object, name)
            except AttributeError:
                print('unable to resolve name {} from object {}'.format(name, containing_object))
                return 1
        # print out source of final reference
        print(inspect.getsource(containing_object))
        return 0
    
    
    if __name__ == '__main__':
        sys.exit(main())
    

    您还可以扩展它以检索尚未使用 importlib 导入的模块的成员

    【讨论】:

      【解决方案2】:

      你需要创建一个实际的对象来传递给get_source,例如:

      In [1]: def add(x,y):
         ...:         return x+y
         ...:
      
      In [2]: def substract(x,y):   return x-y
      
      In [3]: %save my_library.py 1-2
      The following commands were written to file `my_library.py`:
      def add(x,y):
              return x+y
      def substract(x,y):   return x-y
      
      In [4]: import inspect
      
      In [5]: import my_library
      
      In [6]: obj = my_library.substract
      
      In [7]: inspect.getsource(obj)
      Out[7]: 'def substract(x,y):   return x-y\n'
      
      In [8]: obj = my_library.add
      
      In [9]: inspect.getsource(obj)
      Out[9]: 'def add(x,y):\n        return x+y\n'
      
      In [10]:
      

      您可以通过在字符串上使用eval 从字符串生成它们,例如:

      for item in dir(my_library):
           if not item.startswith('_'):
               print(item)
               nam = '.'.join(['my_library', item])
               print(inspect.getsource(eval(nam)))
      

      给予:

      add
      def add(x,y):
              return x+y
      
      substract
      def substract(x,y):   return x-y
      

      【讨论】:

        猜你喜欢
        • 2018-08-21
        • 1970-01-01
        • 2019-03-07
        • 1970-01-01
        • 2021-05-05
        • 1970-01-01
        • 1970-01-01
        • 2017-10-10
        • 1970-01-01
        相关资源
        最近更新 更多