2

I have a python file that is a collection functions, classes with methods etc. I need to parse it so that I can just extract out the specified functions and classes including the methods that I need for the purpose of over-riding them.

Is there a parser that can parse python code well for this kind of requirement? Will the inbuilt ast module help me?

For example:

Input: Main.py

def f_one():
    """
    """
    pass

class c_one():
    """
    """
    def m_one():
    """
    """
    pass

    def m_two():
    """
    """
    pass
    def m_three():
    """
    """
    pass

class c_two():
    def m_one():
    """
    """
    pass

Goal is to just copy across f_one, c_one and m_one, more generally the code (function, class etc) that I specify.

Output: Copy.py

def f_one():
    """
    """
    pass

class c_one():
    """
    """
    def m_one():
    """
    """
    pass
Nishant
  • 20,354
  • 18
  • 69
  • 101
  • 1
    Do you mean `import`? – Daniel Roseman Jul 10 '17 at 13:19
  • No, I am just trying to automate a copy paste work that I do normally. I just described how I copy paste :-) – Nishant Jul 10 '17 at 13:23
  • So you just want to extract the name of each class and function in Main.py? – Toterich Jul 10 '17 at 13:24
  • I would use [import](https://docs.python.org/2/tutorial/modules.html). If you only want to import a class method [this](https://stackoverflow.com/questions/6757192/importing-a-function-from-a-class-in-another-file) might help. // edit: If you only want to pass a function from `main.py` to another function `foo()`, just do `foo(c_one.m_one)`. – P. Siehr Jul 10 '17 at 13:24
  • I don't understand why you are copying and pasting *at all*. That is not something you should be doing. – Daniel Roseman Jul 10 '17 at 13:25
  • Say for example the `Zope Framework`. It has a Template for adding a Controller, Model, Views, Queries to the framework. I can obviously create this Template once and for all. But I was trying to see if there are `Python` code `parsers` that extracts these from an existing Module for example. I am basically trying to copy pase these templates – Nishant Jul 10 '17 at 13:30
  • 1
    Nothing you've said gives a reason not to use `import`. If you want to use `f_one` and `c_one` in another file, you would do `from main import f_one, c_one`. – Daniel Roseman Jul 10 '17 at 13:41
  • They have to renamed :-) I am just using them as *Templates* kind of. – Nishant Jul 10 '17 at 13:55

2 Answers2

3

You can use inspect.getsource()

import inspect
import Main

objects = [Main.f_one, Main.c_one]

copy = ''

#copy objects
for obj in objects:
    copy += inspect.getsource(obj)
    copy += '\n'

with open('Copy.py', 'w') as out:
    out.write(copy)

This writes the full source code of f_one and c_one to Copy.py. If you only want parts of c_one, you would have to inspect all the members that you want seperately (e.g. inspect.getsource(Main.c_one.m_one)) and assemble them manually.

You can also use inspect.getsourcelines() to get an object's source line by line (for instance if you want only the headers).

Note that this is obviously not possible for imports from compiled files.

Toterich
  • 585
  • 2
  • 7
1

You just need to import it:

from Main import f_one, c_one

c = c_one()
c.m_two()
SayPy
  • 536
  • 1
  • 4
  • 13