定义:
通过字符串的形式去操作对象(类,实例对象,模块中的对象)中的成员(增删改查)叫反射。
一、类实例对象
1
2
3
4
5
6
7
8
9
|
class
Foo:
tests
=
'test'
def
__init__(
self
,name,age):
self
.name
=
name
self
.age
=
age
def
show(
self
):
return
"%s - %s"
%
(
self
.name,
self
.age)
obj
=
Foo(
"san"
,
18
)
|
对于以上Foo类实例化出对象obj,在以往我们操作obj中的对象时
print(obj.name)
n = "name"
print(obj.__dict__["name"])
或
print(obj.__dict__[n])
来获取 ojb.name字段
下面用反射来对类实例化对象obj中的字段进行操作
#getattr 获取字段内容
1
2
3
4
5
6
7
8
9
10
|
while
True
:
inp
=
input
(
">>>"
)
#输入要获取的字段对象名
if
hasattr
(obj,inp):
#判断字段是否存在
v
=
getattr
(obj,inp)
if
callable
(v):
#判断是否可调用
print
(v())
else
:
print
(v)
else
:
print
(
"%s 不存在"
%
inp)
|
运行结果:
当输入对象是首先通过hasattr来检查所输入的字段对象是否存在,存在时则打印,不存在给出提示,输入show时,由于show是Foo中的方法,所以被调用,打印出san - 18
#setattr 向对象中赋值字段
1
2
3
4
5
6
7
|
class
Foo:
def
__init__(
self
,name,age):
self
.name
=
name
self
.age
=
age
setattr
(obj,
'sex'
,
"男"
)
#放在obj对象内存中
print
(obj.sex)
|
以上操作等同于obj.sex = "男",往对象中添加字段
同理能添加就能删除
##delattr
# delattr(obj,"name")
# print(obj.name)
这个请自行测试吧
以上是通过类的反射操作对象的字段或方法,下面来说下模块文件中反射
二、模块中反射应用
假设fs2.py中都是网站的功能f1,f2,f3等,通过反射获取并返回值,不存在返回404
这就是python web框架的路由的模拟。
模块文件fs2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
NAME
=
"san"
def
func():
return
'func'
class
Foo:
def
__init__(
self
):
self
.name
=
123
def
f1():
return
"首页"
def
f2():
return
"新闻"
def
f3():
return
"精华"
|
bin.py内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import
fs2
r1
=
fs2.NAME
r2
=
fs2.func()
print
(r1,r2)
r1
=
getattr
(fs2,
"NAME"
)
print
(r1)
r2
=
getattr
(fs2,
'func'
)
print
(r2)
print
(r2())
cls
=
getattr
(fs2,
'Foo'
)
##模块中获取类
print
(
cls
)
obj
=
cls
()
print
(obj)
print
(obj.name)
inp
=
input
(
"请输入要查看的url:"
)
if
hasattr
(fs2,inp):
func
=
getattr
(fs2,inp)
result
=
func()
print
(result)
else
:
print
(
404
)
|
运行结果:
以上完整的模拟了从模块中文件获取全已有变量,函数,类。
本文转自 dyc2005 51CTO博客,原文链接:http://blog.51cto.com/dyc2005/1983803,如需转载请自行联系原作者