0

I hope to get all classes names and fields within each class given a python file say myFile.py. Is there a way to achieve that? I want to pass in myFile.py and get the result.

william007
  • 17,375
  • 25
  • 118
  • 194
  • What exactly do you mean by "field"? Class attributes or instance attributes? And what about properties and other descriptors? – Aran-Fey Apr 04 '18 at 01:26
  • If you're doing this for exploratory purposes, see the [`inspect`](https://docs.python.org/3/library/inspect.html) module, which is basically every helper function you could ever want for doing this and most things like it. – abarnert Apr 04 '18 at 01:28
  • @Aran-Fey What I mean is variable declaration within the class like `abc=1` – william007 Apr 04 '18 at 01:29
  • 3
    Possible duplicate of [Viewing all defined variables](https://stackoverflow.com/questions/633127/viewing-all-defined-variables) – user3483203 Apr 04 '18 at 01:29
  • If you're doing this for some programmatic reason—e.g., to build some kind of plugin interface that auto-loads all of the user's classes—you probably don't want to do this. Instead, you want to come up with some naming standard (like the `unittest` module) or some registration mechanism (like `codecs`) for the classes, and handle just a specific defined subset of all the possible kinds of things that a class could do. – abarnert Apr 04 '18 at 01:30
  • @chrisz but how should I pass in `myFile.py` and get the result? – william007 Apr 04 '18 at 01:31
  • @chrisz I don't think so. That question is asking about the variables defined in the current REPL shell or script, not in some file that he's loading up. – abarnert Apr 04 '18 at 01:31
  • @abarnert maybe, top answer mentions `dir()`, `globals()`, `locals()`. Pretty good start if you want to enumerate methods and attributes. – user3483203 Apr 04 '18 at 01:33
  • 1
    This is a (somewhat) commonly-asked question, so it must be a dup of something with an answer that would help the OP here (the answer is basically just `inspect.getmembers(module)`), but every answer that seems relevant, the questioner already knows about `inspect`… – abarnert Apr 04 '18 at 01:33
  • 1
    @chrisz What good is either `globals` or `locals` going to do for you in enumerating a module or a class in that module? – abarnert Apr 04 '18 at 01:34
  • 1
    Yea may have flagged it as the wrong one – user3483203 Apr 04 '18 at 01:34

1 Answers1

0

Have you considered parsing your Python file with the built-in Abstract Syntax Trees (ast) module, and then examining the results to retrieve the data of interest? Something as simple as:

import ast

def print_info(path):
    with open(path, "r") as src:
        compiled = ast.parse(src.read(), "<string>", "exec")
        for element in compiled.body:
            if isinstance(element, ast.ClassDef):  # we're interested only in classes
                fields = []
                methods = []
                for field in element.body:  # iterate over the class fields/methods
                    if isinstance(field, ast.Assign):  # field assignment
                        for target in field.targets:  # value can be assigned to many fields
                            fields.append(target.id)
                    elif isinstance(field, ast.FunctionDef):  # method definition
                        methods.append(field.name)
                    # etc.
                print("Class: " + element.name)
                print("\tFields:  " + ", ".join(fields))
                print("\tMethods: " + ", ".join(methods))

fulfills your main requirement. For example, if we had a python source file as myFile.py containing:

class A(object):

    name = "A"

    def __init__(self, x):
        self.x = x

class B(object):

    name = "B"
    kind = "Child"

    def instance_method(self):
        pass

    @classmethod
    def class_method(cls):
        pass

    @staticmethod
    def static_method():
        pass

we could easily parse it using the above:

print_info("myFile.py")

And the output would look like:

Class: A
    Fields:  name
    Methods: __init__
Class: B
    Fields:  name, kind
    Methods: instance_method, class_method, static_method

Check the rest of the ast package to see what sort of a data you can extract from it (hint: most of it).

zwer
  • 24,943
  • 3
  • 48
  • 66