别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 辨析

  • Sockets编程

  • Django

  • stackoverflow

  • Flask

  • 全栈之路

    • 基础篇

    • 进阶篇

      • Python 全栈之路系列之迭代器与生成器
      • Python 全栈之路系列之装饰器
      • Python 标准库系列之模块默认全局变量
      • Python 全栈之路系列之异常处理
      • Python 全栈之路系列之文件操作
      • Python 全栈之路系列之递归
      • Python 全栈之路系列之反射
        • 反射的定义
        • 初始反射
        • 反射相关的函数
        • hasattr(object, name)
        • (双下划线)import(双下划线)方式导入多层模块
        • 基于反射模拟 Web 框架路由系统
      • Python 全栈之路系列之正则表达式 re 模块
      • Python 全栈之路系列之字符串格式化
    • 面向对象

    • 网络编程

    • 操作系统

    • 标准库

    • 第三方库

    • Python 全栈之路
  • 面试

  • 代码片段

  • 异步编程

  • 😎Awesome资源

  • PEP

  • Python工匠系列

  • 高阶知识点

  • Python 学习资源待整理
  • 设计模式

  • 好“艹蛋”的 Python 呀!
  • FIFO | 待学清单📝
  • pip 安装及使用
  • 数据分析

  • 源码阅读计划

  • OOP

  • 关于 python 中的 setup.py
  • 并行分布式框架 Celery
  • 七种武器,让你的代码提高可维护性
  • 使用 pdb 调试 Python 代码
  • 每周一个 Python 标准库
  • 🐍Python
  • 全栈之路
  • 进阶篇
佚名
2020-05-23
目录

Python 全栈之路系列之反射

# 反射的定义

根据字符串的形式去某个对象中操作成员

  1. 根据字符串的形式去一个对象中寻找成员
  2. 根据字符串的形式去一个对象中设置成员
  3. 根据字符串的形式去一个对象中删除成员
  4. 根据字符串的形式去一个对象中判断成员是否存在

# 初始反射

通过字符串的形式,导入模块

根据用户输入的模块名称,导入对应的模块并执行模块中的方法

# Python使用的是3.5.1
[root@ansheng ~]# python -V
Python 3.5.1
# commons.py为模块文件
[root@ansheng ~]# ls
commons.py  reflection.py
# commons.py文件内容
[root@ansheng ~]# cat commons.py 
#!/usr/bin/env python
# 定义了连个函数,f1和f2
def f1():
    return "F1"

def f2():
    return "F2"
[root@ansheng ~]# cat reflection.py 
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# 输入模块的名称
mod_name = input("请输入模块名称>>> ")
# 查看输入的内容及数据类型
print(mod_name, type(mod_name))
# 通过__import__的方式导入模块,并赋值给dd
dd = __import__(mod_name)
# 执行f1()函数
ret = dd.f1()
# 输出函数的返回值
print(ret)
# 执行reflection.py 
[root@ansheng ~]# python reflection.py 
# 输入模块名称
请输入模块名称>>> commons
# 返回输入的内容及数据类型
commons <class 'str'>
# 执行F1函数
F1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

通过字符串的形式,去模块中寻找指定函数,并执行

用户输入模块名称和函数名称,执行指定模块内的函数 or 方法

[root@ansheng ~]# cat commons.py 
#!/usr/bin/env python

def f1():
    return "F1"

def f2():
    return "F2"
[root@ansheng ~]# cat reflection.py 
#!/usr/bin/env python
# _*_ coding:utf-8 _*_

# 输入模块的名称
mod_name = input("请输入模块名称>>>")

# 输入函数or方法的名称
func_name = input("请输入函数名称>>>")

# 导入模块
dd = __import__(mod_name)

# 导入模块中的方法
target_func = getattr(dd, func_name)

# 查看target_func和dd.f1的内存地址
print(id(target_func), id(dd.f1))

# 执行target_func()函数
result = target_func()

# 输出结果
print(result)
[root@ansheng ~]# python reflection.py
# 输入模块名称commons
请输入模块名称>>>commons
# 输入函数名称f1
请输入函数名称>>>f1
# 返回内存地址
139844714989224 139844714989224
# 执行的函数返回结果
F1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 反射相关的函数

getattr(object, name[, default])

根据字符串的形式去一个对象中寻找成员

# 自定义模块的内容
[root@ansheng ~]# cat commons.py 
#!/usr/bin/env python

Blog_Url = "https://blog.ansheng.me"

def f1():
    return "F1"

def f2():
    return "F2"
1
2
3
4
5
6
7
8
9
10
11
>>> import commons
>>> getattr(commons, "f1")
<function f1 at 0x7fbce5774598>
>>> getattr(commons, "f1f1f1")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'commons' has no attribute 'f1f1f1'
1
2
3
4
5
6
7

执行获取到的函数

>>> target_func = getattr(commons, "f1")
>>> target_func
<function f1 at 0x7fbce5774598>
>>> target_func() 
'F1'
1
2
3
4
5

通过设置默认值可以避免获取不到方法时报错

# 设置一个默认值为None
>>> target_func = getattr(commons, "f1f1f1", None)
>>> target_func
>>> 
1
2
3
4

通过 getattr 获取模块中的全局变量

>>> import commons
>>> getattr(commons, "Blog_Url", None)
'https://blog.ansheng.me'
1
2
3
  • setattr(object, name, value)

根据字符串的形式去一个对象中设置成员

设置全局变量

# 获取commons内的Name变量
>>> getattr(commons, "Name", None)
# 在commons模块中设置一个全局变量Name,值为Ansheng
>>> setattr(commons, "Name", "Ansheng")
# 获取commons内的Name变量
>>> getattr(commons, "Name", None)
'Ansheng'
1
2
3
4
5
6
7

getattr 结合 lambda 表达式设置一个函数

>>> setattr(commons, "as", lambda : print("as"))
>>> getattr(commons, "as")
<function <lambda> at 0x000001FD3E51FD90>
>>> aa = getattr(commons, "as")
>>> aa()
as
1
2
3
4
5
6
  • delattr(object, name)

根据字符串的形式去一个对象中删除成员

>>> getattr(commons, "Name")
'Ansheng'
>>> delattr(commons, "Name")
# 获取不到就报错
>>> getattr(commons, "Name")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'commons' has no attribute 'Name'
1
2
3
4
5
6
7
8

# hasattr(object, name)

根据字符串的形式去一个对象中判断成员是否存在

# 如果不存在就返回False
>>> hasattr(commons, "Name")
False
>>> setattr(commons, "Name", "Ansheng")
# 如果存在就返回True
>>> hasattr(commons, "Name")
True
1
2
3
4
5
6
7

# (双下划线)import(双下划线)方式导入多层模块

>>> m = __import__("lib.commons")     
>>> m
# 返回的路径是`lib`
<module 'lib' (namespace)>
>>> m = __import__("lib.commons", fromlist=True)
>>> m
# 返回的路径是`lib.commons`
<module 'lib.commons' from '/root/lib/commons.py'>
1
2
3
4
5
6
7
8

# 基于反射模拟 Web 框架路由系统

find_index.py文件内容

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

url = input("请输入url: ")
target_module, target_func = url.split('/')

m = __import__("lib." + target_module, fromlist=True)

if hasattr(m, target_func):
    target_func = getattr(m, target_func)
    r = target_func()
    print(r)
else:
    print("404")
1
2
3
4
5
6
7
8
9
10
11
12
13
14

目录结构及文件内容

[root@ansheng ~]# tree ./
./
├── find_index.py
└── lib
    ├── account.py
    └── commons.py

1 directory, 3 files
[root@ansheng ~]# cat lib/commons.py 
#!/usr/bin/env python

Blog_Url = "https://blog.ansheng.me"

def f1():
    return "F1"

def f2():
    return "F2"
[root@ansheng ~]# cat lib/account.py 
#!/usr/bin/env python
# _*_ coding:utf-8 _*_

def login():
    return "login"

def logout():
    return "logout"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

执行

[root@ansheng ~]# python find_index.py 
请输入url: account/login
login
[root@ansheng ~]# python find_index.py 
请输入url: account/logout
logout
[root@ansheng ~]# python find_index.py 
请输入url: commons/f1
F1
[root@ansheng ~]# python find_index.py 
请输入url: commons/f2
F2
[root@ansheng ~]# python find_index.py 
请输入url: commons/asdasd
404
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
编辑 (opens new window)
#编码
上次更新: 2024-07-23, 01:00:43
Python 全栈之路系列之递归
Python 全栈之路系列之正则表达式 re 模块

← Python 全栈之路系列之递归 Python 全栈之路系列之正则表达式 re 模块→

最近更新
01
2025 面试记录
05-28
02
提升沟通亲和力的实用策略
03-26
03
工作
07-15
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式