苦练Python第41天:如何用dir() 函数“透视一切”

前言

大家好,我是 倔强青铜三 。欢迎关注我,微信公众号:倔强青铜三。欢迎点赞、收藏、关注,一键三连!

欢迎来到 苦练Python第 41 天

今天,我们把"平平无奇"的内置函数 dir() 玩出花:无参速查模块透视类与对象解剖动态调试过滤黑科技IDE 补全模拟,一站式教你写出"看谁都像裸奔"的代码审计脚本。


🧠 dir() 的本质

python 复制代码
>>> dir()
['__builtins__', '__name__', ...]

记住:无参数时,它只返回当前作用域内"已定义"的名字列表(字符串排序版)

想深入模块、类、对象?把目标作为参数丢给它!


🎯 场景一:无参速查------我刚定义了啥?

python 复制代码
>>> a = [1, 2, 3]
>>> def hello(): pass
>>> dir()
['__builtins__', '__name__', 'a', 'hello']

技巧 :配合 set 做"前后快照",快速找差异。

python 复制代码
_before = set(dir())
# ... 运行某段代码 ...
_after  = set(dir())
print(_after - _before)   # 新引入的名字

🎯 场景二:模块透视------包里装了哪些子弹?

python 复制代码
>>> import math
>>> dir(math)[:10]
['__doc__', '__loader__', '__name__', 'acos', 'acosh', 'asin', 'asinh',
 'atan', 'atan2', 'atanh']

实战:快速定位模块是否包含目标函数。

python 复制代码
hasattr(math, 'isqrt')          # 推荐
'isqrt' in dir(math)            # 一样效果,但可读性高

🎯 场景三:类与对象解剖------实例到底能点出哪些方法?

python 复制代码
class Dog:
    def bark(self): pass
    def eat(self): pass

>>> dir(Dog)          # 类的武器库
['__class__', '__doc__', ..., 'bark', 'eat']

>>> d = Dog()
>>> dir(d)            # 实例的武器库(与类基本一致)
['__class__', '__dict__', ..., 'bark', 'eat']

进阶:去掉魔法方法,只看业务接口。

python 复制代码
[name for name in dir(Dog) if not name.startswith('_')]
# ['bark', 'eat']

🎯 场景四:动态调试------运行时注入补丁

python 复制代码
import requests

# 1. 看 requests 有哪些可 monkey patch 的点
>>> dir(requests)
['ConnectTimeout', 'ConnectionError', ..., 'get', 'post']

# 2. 快速确认 session 对象可调用的方法
>>> dir(requests.Session())[:5]
['__attrs__', '__class__', '__delattr__', '__dict__', '__dir__']

技巧 :在断点调试时,直接用 dir(obj) 探索陌生对象。


🎯 场景五:过滤黑科技------只看"公有 API"

python 复制代码
import keyword

def public_names(obj):
    return [n for n in dir(obj)
            if not n.startswith('_') and not keyword.iskeyword(n)]

>>> public_names(str)[:8]
['capitalize', 'casefold', 'center', 'count', 'encode', 'endswith',
 'expandtabs', 'find']

🎯 场景六:IDE 补全模拟------给 Jupyter 写个 Tab 键

python 复制代码
def _jupyter_lab_completion_map(obj, prefix=''):
    """返回以 prefix 开头的补全列表"""
    return [name for name in dir(obj) if name.startswith(prefix)]

>>> _jupyter_lab_completion_map(str, 'is')
['isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier',
 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper']

🛠️ 封装成万能工具函数

python 复制代码
def dir_plus(obj=None, *, public_only=False, prefix=''):
    """
    增强版 dir()
    obj:        要查看的对象,None 表示当前作用域
    public_only:True 过滤私有/魔法名称
    prefix:     只保留以该前缀开头的名字
    """
    names = dir(obj) if obj is not None else dir()
    if public_only:
        names = [n for n in names if not n.startswith('_')]
    if prefix:
        names = [n for n in names if n.startswith(prefix)]
    return names

# 使用示例
>>> dir_plus(str, public_only=True, prefix='r')
['removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex',
 'rjust', 'rpartition', 'rsplit', 'rstrip']

📄 JSON 配置检查器:动态校验键值

python 复制代码
import json, keyword

cfg = json.loads('{"class": 1, "for": "loop"}')
bad_keys = [k for k in cfg if keyword.iskeyword(k)]
if bad_keys:
    print("非法关键字键:", bad_keys)
else:
    print("配置键合法")

🔧 速查表

需求 一行代码
当前作用域名字 dir()
模块公共接口 dir_plus(module, public_only=True)
类实例可调方法 dir_plus(instance, public_only=True)
补全提示 dir_plus(obj, prefix='get')
排除魔法方法 [n for n in dir(obj) if not n.startswith('_')]

✅ 一句话总结

dir() 本身只是"名单",用好过滤 + 封装,就能在调试、探索、元编程三大战场横着走!

最后感谢阅读!欢迎关注我,微信公众号倔强青铜三。欢迎 点赞收藏关注,一键三连!

相关推荐
胡gh5 分钟前
你一般用哪些状态管理库?别担心,Zustand和Redux就能说个10分钟
前端·面试·node.js
维基框架7 分钟前
维基框架 (Wiki Framework) 1.1.0 版本发布 提供多模型AI辅助开发
人工智能
西猫雷婶18 分钟前
神经网络|(十二)概率论基础知识-先验/后验/似然概率基本概念
人工智能·神经网络·机器学习·回归·概率论
闲人编程28 分钟前
Python第三方库IPFS-API使用详解:构建去中心化应用的完整指南
开发语言·python·去中心化·内存·寻址·存储·ipfs
计算机编程小咖1 小时前
《基于大数据的农产品交易数据分析与可视化系统》选题不当,毕业答辩可能直接挂科
java·大数据·hadoop·python·数据挖掘·数据分析·spark
居7然1 小时前
大模型微调面试题全解析:从概念到实战
人工智能·微调
zhangfeng11332 小时前
以下是基于图论的归一化切割(Normalized Cut)图像分割工具的完整实现,结合Tkinter界面设计及Python代码示
开发语言·python·图论
haidizym2 小时前
质谱数据分析环节体系整理
大数据·人工智能·数据分析·ai4s
Godspeed Zhao2 小时前
Tesla自动驾驶域控制器产品(AutoPilot HW)的系统化梳理
人工智能·机器学习·自动驾驶
fsnine3 小时前
机器学习案例——预测矿物类型(模型训练)
人工智能·机器学习