inspect python_python--inspect

inspect是专门用来收集python对象的信息的,可以获取参数信息,原码,解析堆栈,判断对象类型等等。下面看看一些主要用法

import inspect

# 1.判断是不是一个模块

import tornado

print(inspect.ismodule(tornado)) # True

# 2.判断是不是一个类

Foo = type("Foo", (object, ), {})

print(inspect.isclass(Foo)) # True

# 3.判断是不是一个方法。说白了就是判断是不是类里面定义的一个函数,

class A:

def m(self):

...

print(inspect.ismethod(A().m), type(A().m)) # True

# 4.判断是不是一个方法描述符。说白了就是首先得是一个类的实例对象,并且这个类里面定义了__get__方法,且没有定义__set__方法

class A:

def __get__(self, instance, owner):

...

print(inspect.ismethoddescriptor(A()))

# 5.判断是不是一个数据描述符。说白了就是首先得是一个类的实例对象,并且这个类里面定义了__get__方法和__set__方法

class A:

def __get__(self, instance, owner):...

def __set__(self, instance, value):...

print(inspect.isdatadescriptor(A())) # True

# 6.判断是不是一个函数

print(inspect.isfunction(lambda: ...)) # True

# 7.判断是不是一个生成器函数

def foo(): yield 1

print(inspect.isgeneratorfunction(foo)) # True

# 同时生成器函数也是一个函数

print(inspect.isfunction(foo)) # True

# 8.判断是不是一个协程函数,协程函数必须是由async def语法定义的函数,使用types.coroutine或者asyncio.coroutine装饰的函数都不是

async def foo():

...

print(inspect.iscoroutinefunction(foo)) # True

# 9.判断是不是一个异步生成器函数,异步生成器函数是由async def语法定义,并且函数体内部要包含yield的函数

async def foo():

yield 1

print(inspect.isasyncgenfunction(foo)) # True

# 10.判断是不是一个异步生成器,就是异步生成器函数加上小括号

print(inspect.isasyncgen(foo())) # True

# 11.判断是不是一个生成器, 就是生成器函数加上小括号

def gen(): yield 1

print(inspect.isgenerator(gen())) # True

# 12.判断是不是一个协程,就是协程函数加上小括号

async def foo(): ...

print(inspect.iscoroutine(foo())) # True

# 13.判断是不是一个可以awaitable,说白了就是await一个迭代器对象

async def foo():

await [1, 2, 3].__iter__()

print(inspect.isawaitable(foo())) # True

# 14.判断是不是一个栈帧

def foo():

# 该函数可以获取栈帧

frame = inspect.currentframe()

return frame

print(inspect.isframe(foo())) # True

# 15.判断是是不是code

def foo(): ...

print(inspect.iscode(foo.__code__)) # True

# 16.获取成员

class A:

def __init__(self):...

def parse(self): ...

import pprint

pprint.pprint(inspect.getmembers(A))

‘‘‘

[(‘__class__‘, ),

(‘__delattr__‘, ),

(‘__dict__‘,

mappingproxy({‘__dict__‘: ,

‘__doc__‘: None,

‘__init__‘: ,

‘__module__‘: ‘__main__‘,

‘__weakref__‘: ,

‘parse‘: })),

(‘__dir__‘, ),

(‘__doc__‘, None),

(‘__eq__‘, ),

(‘__format__‘, ),

(‘__ge__‘, ),

(‘__getattribute__‘, ),

(‘__gt__‘, ),

(‘__hash__‘, ),

(‘__init__‘, ),

(‘__init_subclass__‘,

),

(‘__le__‘, ),

(‘__lt__‘, ),

(‘__module__‘, ‘__main__‘),

(‘__ne__‘, ),

(‘__new__‘, ),

(‘__reduce__‘, ),

(‘__reduce_ex__‘, ),

(‘__repr__‘, ),

(‘__setattr__‘, ),

(‘__sizeof__‘, ),

(‘__str__‘, ),

(‘__subclasshook__‘,

),

(‘__weakref__‘, ),

(‘parse‘, )]

‘‘‘

# 17.获取mro,包括自己

class A(object): ...

print(inspect.getmro(A)) # (, )

# 18.获取doc

print(inspect.getdoc(int))

‘‘‘

int([x]) -> integer

int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments

are given. If x is a number, return x.__int__(). For floating point

numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,

bytes, or bytearray instance representing an integer literal in the

given base. The literal can be preceded by ‘+‘ or ‘-‘ and be surrounded

by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.

Base 0 means to interpret the base from the string as an integer literal.

>>> int(‘0b100‘, base=0)

4

‘‘‘

# 19.查看对象被定义在哪一个文件里面

from pandas import DataFrame

print(inspect.getfile(DataFrame)) # C:\python37\lib\site-packages\pandas\core\frame.py

# 当然也可以是一个模块

import requests

print(inspect.getfile(requests)) # C:\python37\lib\site-packages\requests\__init__.py

# 20.返回一个给定对象的模块名,不过存在不存在,感觉没卵用

print(inspect.getmodulename(r"C:\python37\lib\site-packages\peeaaawee.py")) # peeaaawee

# 21.和getfile类似

print(inspect.getabsfile(DataFrame)) # c:\python37\lib\site-packages\pandas\core\frame.py

# 22.获取参数信息,但需要传入字节码

def foo(a, b=1): ...

print(inspect.getargs(foo.__code__)) # Arguments(args=[‘a‘, ‘b‘], varargs=None, varkw=None)

print(inspect.getargs(foo.__code__).args) # [‘a‘, ‘b‘]

# 23.获取参数信息吗, 传入函数即可

def foo(a, b=1): ...

print(inspect.getfullargspec(foo)) # FullArgSpec(args=[‘a‘, ‘b‘], varargs=None, varkw=None, defaults=(1,), kwonlyargs=[], kwonlydefaults=None, annotations={})

print(foo.__defaults__) # (1,)

import inspect

def bar():

name = "Mashiro"

age = 16

return foo()

def foo():

name = "Satori"

age = 18

return inspect.currentframe()

# frame叫做栈帧,表示当前函数调用栈的某一帧,是一个上下文。正所谓在python中一切皆对象,这个栈帧也是一个对象。

# 函数执行要在相应的栈帧中执行

# 栈帧有一下几大特性,

# f_back:调用者的上一级栈帧

# f_code:字节码

# f_lineno:栈帧所在的哪一行

# frame是定义在foo函数里面,所以currentframe拿到的是foo的栈帧

# 但是又是通过bar来调用的,所以foo的上一级栈帧就是bar的栈帧

f = bar()

print(f.f_back) #

print(f.f_code) #

print(f.f_lineno) # 13

# 这个f_code里面也有很多的属性

# co_name:获取栈帧所对应的函数名

print(f.f_code.co_name) # foo

# co_filename:获取相应的文件名

print(f.f_code.co_filename) # D:/乱七八糟的/龙卷风/3.py

print(f.f_back.f_code.co_name) # bar

print(f.f_back.f_code.co_filename) # D:/乱七八糟的/龙卷风/3.py

# 查看当前的局部变量,可以看到由于栈帧还在,所以局部变量依旧存储在堆上

print(f.f_locals) # {‘name‘: ‘Satori‘, ‘age‘: 18}

# 同理它的上一级栈帧也是

print(f.f_back.f_locals) # {‘name‘: ‘Mashiro‘, ‘age‘: 16}

# 如果是生成器的话,就不需要了

def gen():

yield 1

name = ("xxx", )

yield 2

age = 16

yield 3

gender = "f"

yield 4

return

g = gen()

# 生成器有一个gi_frame属性,可以直接获取

print(g.gi_frame.f_locals) # {}

print(next(g)) # 1

print(g.gi_frame.f_locals) # {}

print(next(g)) # 2

print(g.gi_frame.f_locals) # {‘name‘: ‘xxx‘}

print(next(g)) # 3

print(g.gi_frame.f_locals) # {‘name‘: ‘xxx‘, ‘age‘: 16}

print(next(g)) # 4

print(g.gi_frame.f_locals) # {‘name‘: ‘xxx‘, ‘age‘: 16, ‘gender‘: ‘f‘}

try:

next(g)

except StopIteration as e:

print(e.value) # result

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值