python反射解析
一. 简介
python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。
二. 使用
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
|
class
Foo(
object
):
def
__init__(
self
):
self
.name
=
'wupeiqi'
def
func(
self
):
return
'func'
obj
=
Foo()
# #### 检查是否含有成员 ####
hasattr
(obj,
'name'
)
hasattr
(obj,
'func'
)
# #### 获取成员 ####
getattr
(obj,
'name'
)
getattr
(obj,
'func'
)
# #### 设置成员 ####
setattr
(obj,
'age'
,
18
)
setattr
(obj,
'show'
,
lambda
num: num
+
1
)
# #### 删除成员 ####
delattr
(obj,
'name'
)
delattr
(obj,
'func'
)
|
详细解析:
当我们要访问一个对象的成员时,应该是这样操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class
Foo(
object
):
def
__init__(
self
):
self
.name
=
'alex'
def
func(
self
):
return
'func'
obj
=
Foo()
# 访问字段
obj.name
# 执行方法
obj.func()
|
那么问题来了?
a、上述访问对象成员的 name 和 func 是什么?
答:是变量名
b、obj.xxx 是什么意思?
答:obj.xxx 表示去obj中或类中寻找变量名 xxx,并获取对应内存地址中的内容。
c、需求:请使用其他方式获取obj对象中的name变量指向内存中的值 “alex”
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
|
# 第一种方式
class
Foo(
object
):
def
__init__(
self
):
self
.name
=
'alex'
def
func(
self
):
return
'func'
# 不允许使用 obj.name
obj
=
Foo()
print
(obj.__dict__[
'name'
])
# 第二种方式
class
Foo(
object
):
def
__init__(
self
):
self
.name
=
'alex'
def
func(
self
):
return
'func'
# 不允许使用 obj.name
obj
=
Foo()
print
(
getattr
(obj,
'name'
))
|
WEB框架实例
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
|
#!/usr/bin/env python
#coding:utf-8
from
wsgiref.simple_server
import
make_server
class
Handler(
object
):
def
index(
self
):
return
'index'
def
news(
self
):
return
'news'
def
RunServer(environ, start_response):
start_response(
'200 OK'
, [(
'Content-Type'
,
'text/html'
)])
url
=
environ[
'PATH_INFO'
]
temp
=
url.split(
'/'
)[
1
]
obj
=
Handler()
is_exist
=
hasattr
(obj, temp)
if
is_exist:
func
=
getattr
(obj, temp)
ret
=
func()
return
ret
else
:
return
'404 not found'
if
__name__
=
=
'__main__'
:
httpd
=
make_server('',
8001
, RunServer)
print
"Serving HTTP on port 8000..."
httpd.serve_forever()
|
结论:反射是通过字符串的形式操作对象相关的成员。一切事物都是对象!
反射当前模块成员
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import
sys
def
s1():
print
(
's1'
)
def
s2():
print
(
's2'
)
this_module
=
sys.modules[__name__]
hasattr
(this_module,
's1'
)
getattr
(this_module,
's2'
)
|
类也是对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class
Foo(
object
):
staticField
=
"old boy"
def
__init__(
self
):
self
.name
=
'wupeiqi'
def
func(
self
):
return
'func'
@staticmethod
def
bar():
return
'bar'
print
getattr
(Foo,
'staticField'
)
print
getattr
(Foo,
'func'
)
print
getattr
(Foo,
'bar'
)
|
模块也是对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
程序目录:
home.py
index.py
home.py:
def dev():
return 'dev'
当前文件:
index.py
"""
import
home as obj
#obj.dev()
func
=
getattr
(obj,
'dev'
)
func()
|