inspect库的中阶学习

1. 获取类与类成员信息

import inspect

class AdvancedClass:
    """This is an advanced class for demonstration."""
    
    def __init__(self, a, b):
        self.a = a
        self.b = b
    
    @staticmethod
    def static_method():
        pass
    
    @classmethod
    def class_method(cls):
        pass
    
    def instance_method(self):
        """Instance method docstring."""
        pass

# 获取类的所有成员(包括方法、属性等)
members = inspect.getmembers(AdvancedClass, predicate=inspect.isroutine)
for name, member in members:
    if hasattr(member, '__func__'):  # 对于非静态方法,获取未绑定的方法对象
        member = member.__func__
    print(f"{name}: {inspect.signature(member)}")

# 获取类的类变量、实例变量等所有定义的属性
class_attributes = [a for a, _ in inspect.classify_class_attrs(AdvancedClass)]
print("Class Attributes:", class_attributes)

# 检查成员类型
for attr in class_attributes:
    kind = attr.kind
    if kind == 'method':
        print(f"{attr.name} is a {kind} and its definition is:")
        print(inspect.getsource(attr.defining_class.__dict__[attr.name]))

2. 使用getclosurevars()理解闭包

def outer(a):
    b = 10
    def inner(c):
        nonlocal b
        return a + b + c
    return inner

inner_func = outer(5)
closure_info = inspect.getclosurevars(inner_func)
print("Closure Variables:")
print("Nonlocals:", closure_info.nonlocals)  # 输出非局部变量
print("Globals:", closure_info.globals)     # 输出全局变量
print("Builtins:", closure_info.builtins)   # 输出内置模块引用

3. 深入元类和堆栈跟踪

class Meta(type):
    def __new__(metacls, name, bases, namespace, **kwargs):
        print(f"Meta.__new__() called with {namespace}")
        return super().__new__(metacls, name, bases, namespace)

class WithMeta(metaclass=Meta):
    x = "A class attribute"

# 使用inspect模块查看元类创建类时的信息
print("\nMeta-class creation information:")
frame = inspect.currentframe()
callers_locals = inspect.getargvalues(frame).locals
print(callers_locals['WithMeta'])

# 获得调用堆栈详细信息
traceback = inspect.trace()
for frameinfo in traceback:
    print(f"\nFile: {frameinfo.filename}, Line: {frameinfo.lineno}, Function: {frameinfo.function}")
    if frameinfo.function == "":
        source_lines, line_number = inspect.getsourcelines(frameinfo.frame)
        print("Source code lines:")
        for line in source_lines:
            print(line.strip())

以上示例展示了如何使用inspect库来深入分析类结构、闭包环境以及元类创建过程和调用堆栈。在实际编程中,这些功能可以帮助你更好地理解代码结构,进行调试和自动化处理。同时,请确保查阅官方文档以了解inspect模块的完整应用。

你可能感兴趣的:(python)