Skip to content
Search

Python:inspect

lastmod 2024-07-04created 2020-05-0312 edits

The inspect module provides several useful functions to help get information about live objects such as modules, classes, methods, functions, tracebacks, frame objects, and code objects. For example, it can help you examine the contents of a class, retrieve the source code of a method, extract and format the argument list for a function, or get all the information you need to display a detailed traceback.

This module provides four main kinds of services

  • Type checking
  • Getting source code
  • Inspecting classes and functions
  • Examining the interpreter stack

Types and members

The getmembers() function retrieves the members of an object such as a class or module. The functions whose names begin with is are mainly provided as convenient choices for the second argument to getmembers(). They also help you determine when you can expect to find the following special attributes:

Type

Attribute

Description

Module

doc

Documentation string

file

File name (missing for built-in modules)

Class

doc

Documentation string

name

Name with which this class was defined

qualname

Qualified name

module

Name of the module in which this class was defined

Method

doc

Documentation string

name

Name with which this method was defined

qualname

Qualified name

func

Function object containing the implementation of the method

self

Instance to which this method is bound, or None

module

Name of the module in which this method was defined

Function

doc

Documentation string

name

Name with which this function was defined

qualname

Qualified name

code

Code object containing the compiled function bytecode

defaults

Tuple of default values for positional or keyword parameters

kwdefaults

Mapping of default values for keyword-only parameters

globals

Global namespace in which this function was defined

annotations

Mapping of parameter names to annotations; the "return" key is reserved for return annotations.

module

Name of the module in which this function was defined

Traceback

tb_frame

Frame object at this level

tb_lasti

Index of the last attempted instruction in bytecode

tb_lineno

Current line number in Python source code

tb_next

Next inner traceback object (called by this level)

Frame

f_back

Next outer frame object (this frame's caller)

f_builtins

Built-in namespace seen by this frame

f_code

Code object being executed in this frame

f_globals

Global namespace seen by this frame

f_lasti

Index of the last attempted instruction in bytecode

f_lineno

Current line number in Python source code

f_locals

Local namespace seen by this frame

f_trace

Tracing function for this frame, or None

Code

co_argcount

Number of arguments (not including keyword-only arguments, * or ** args)

co_code

String of raw compiled bytecode

co_cellvars

Tuple of names of cell variables (referenced by containing scopes)

co_consts

Tuple of constants used in the bytecode

co_filename

Name of the file in which this code object was created

co_firstlineno

Number of the first line in Python source code

co_flags

Bitmap of CO_* flags, read more here

co_lnotab

Encoded mapping of line numbers to bytecode indices

co_freevars

Tuple of names of free variables (referenced via a function's closure)

co_posonlyargcount

Number of positional-only arguments

co_kwonlyargcount

Number of keyword-only arguments (not including ** arg)

co_name

Name with which this code object was defined

co_names

Tuple of names of local variables

co_nlocals

Number of local variables

co_stacksize

Virtual machine stack space required

co_varnames

Tuple of names of arguments and local variables

Generator

name

Name

qualname

Qualified name

gi_frame

Frame

gi_running

Is the generator running?

gi_code

Code

gi_yieldfrom

Object being iterated by yield from, or None

Coroutine

name

Name

qualname

Qualified name

cr_await

Object being awaited, or None

cr_frame

Frame

cr_running

Is the coroutine running?

cr_code

Code

cr_origin

Where the coroutine was created, or None. See sys.set_coroutine_origin_tracking_depth()

Built-in

doc

Documentation string

name

Original name of this function or method

qualname

Qualified name

self

Instance to which the method is bound, or None

getmembers

getdoc

Gets the documentation comment string. Mainly uses attributes such as __doc__.

Get docstring of class attribute

To get a docstring comment added to a class Attribute, see Python:ast#Get docstring of class attribute.

getfullargspec

def foo(a, b, c=4, *arglist, **keywords):
    pass

print(inspect.getfullargspec(foo))

The output is as follows.

(['a', 'b', 'c'], 'arglist', 'keywords', (4,))

Since Python 3.3, #signature is available.

signature

A Signature object represents the call signature of a callable object and its return annotation. To retrieve a Signature object, use the signature() function.

Example:

from inspect import signature
def foo(a, *, b:int, **kwargs):
    pass

sig = signature(foo)
str(sig)
str(sig.parameters['b'])
sig.parameters['b'].annotation

Signature class

A Signature object represents the call signature of a function and its return annotation. For each parameter accepted by the function, it stores a Parameter object in its parameters collection.

replace

Lets you change the signature stored in the object. (It does not change the signature of the original symbol.)

bind(*args, **kwargs)

Creates a mapping from positional and keyword arguments to parameters. Returns #BoundArguments if *args and **kwargs match the signature, or raises a TypeError otherwise.

You can use this function to adjust the required argument passing dynamically.

def foo(a, b='ham', *args):
    pass

sig = inspect.signature(foo)
ba = sig.bind('spam')
ba.apply_defaults()
print(ba.arguments)

foo(*ba.args, **ba.kwargs)

BoundArguments

Result of a Signature.bind() or Signature.bind_partial() call. Holds the mapping of arguments to the function's parameters.

apply_defaults

Fills in missing arguments with their default values, if any.

def foo(a, b='ham', *args):
    pass

ba = inspect.signature(foo).bind('spam')
ba.apply_defaults()
print(ba.arguments)

Code information

func = lambda x, y: (x, y)
func.__code__.co_argcount
func.__code__.co_varnames

Inspecting the init function

class Super:
    def __init__(self, name, kwarg='default'):
        print('instantiated')
        self.name = name

>>> import inspect
>>> inspect.signature(Super.__init__)
<Signature (self, name, kwarg='default')>

Finding all classes in the current file that inherit from a given class

# -*- coding: utf-8 -*-

from typing import Type, Dict
from recc.exception.base_exception import ReccBaseException

CODE_RECC_OK = 0
CODE_RECC_ERROR = 10


class ReccOk(ReccBaseException):
    def __init__(self, *args, code=CODE_RECC_OK):
        super().__init__(*args, code=code)
        assert self.is_recc_code()


class ReccError(ReccBaseException):
    def __init__(self, *args, code=CODE_RECC_ERROR):
        super().__init__(*args, code=code)
        assert self.is_recc_code()


def get_recc_code_to_error_type_map() -> Dict[int, Type[ReccBaseException]]:
    from inspect import getmembers, isclass
    from sys import modules

    def _is_recc_error_type(x) -> bool:
        return isclass(x) and issubclass(x, ReccBaseException)

    result = dict()
    class_members = getmembers(modules[__name__], _is_recc_error_type)
    for member in class_members:
        class_name = member[0]
        class_type = member[1]
        assert isinstance(class_name, str)
        assert isinstance(class_type, type)
        assert issubclass(class_type, ReccBaseException)
        instance: ReccBaseException = class_type()
        assert instance.is_unknown_code() or instance.is_recc_code()
        result[instance.code] = class_type
    return result


RECC_CODE_TO_ERROR_TYPE_MAP = get_recc_code_to_error_type_map()

How to find the variable names of variables passed in a function call

WARNING

Not recommended.

import inspect

def foo(a, f, b):
    frame = inspect.currentframe()
    frame = inspect.getouterframes(frame)[1]
    string = inspect.getframeinfo(frame[0]).code_context[0].strip()
    args = string[string.find('(') + 1:-1].split(',')

    names = []
    for i in args:
        if i.find('=') != -1:
            names.append(i.split('=')[1].strip())

        else:
            names.append(i)

    print names

def main():
    e = 1
    c = 2
    foo(e, 1000, b = c)

main()

Output:

['e', '1000', 'c']

See also

Favorite site

author Zer0 sitemap