[原文]
python的對象反射功能,經常在編程時使用.相比較其它的編程語言使用非常方便.反射就是用字符串來操作對象或者類,模塊中的成員.
一.對象的反射
反射功能的實現,由這4個內置函數來實現(hasattr, getattr, setattr, delattr)
1.1.hasattr判斷是否有某個成員
判斷對象中是否有屬性, 方法.返回bool值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#!/usr/bin/env python
# -*-coding:utf-8-*-
class
Foo
(
object
)
:
country
=
"china"
def
__init__
(
self
,
name
)
:
self
.name
=
name
def
f
(
self
)
:
print
"function f"
obj
=
Foo
(
"abc"
)
print
hasattr
(
obj
,
"name"
)
#判斷是否有name字段,返回True
print
hasattr
(
obj
,
"f"
)
#判斷是否有f方法,返回True
print
hasattr
(
obj
,
"ok"
)
#沒有這個方法,返回False
print
hasattr
(
obj
,
"country"
)
#判斷有沒有靜態字段,返回True
print
hasattr
(
Foo
,
"country"
)
#使用類作為參數來判斷
print
"class:"
,
Foo
.__dict__
.keys
(
)
print
"obj:"
,
obj
.__dict__
.keys
(
)
|
上例中使用對象作為obj參數來判斷,是否有類的靜態方法.也是可以的.因為對象的特殊性,先在對象中找是否有該成員,如果沒在,通過對象指針,在去創建這個對象的類中找查
執行結果
1
2
3
4
5
6
7
|
True
True
False
True
True
class
:
[
'__module__'
,
'f'
,
'country'
,
'__dict__'
,
'__weakref__'
,
'__doc__'
,
'__init__'
]
obj
:
[
'name'
]
|
1.2.獲取對象的成員
也可以使用對象來獲取類的成員.和上例中的hasattr一樣
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-*-
class
Foo
(
object
)
:
country
=
"china"
def
__init__
(
self
,
name
)
:
self
.name
=
name
def
f
(
self
)
:
print
"this is function = "
,
self
.name
obj
=
Foo
(
"abc"
)
print
getattr
(
obj
,
"name"
)
#獲取對象的name字段
f
=
getattr
(
obj
,
"f"
)
#通過對象獲取類的方法
print
f
#打印出來是信類的方法
f
(
)
#加上括號就能直接調用執行這個的方法
print
getattr
(
Foo
,
"country"
)
print
getattr
(
obj
,
"country"
)
#使用對象也能找到靜態字段
|
1.3.增加對象或者類的成員
動態的增加對象或者類中的成員
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#!/usr/bin/env python
# -*-coding:utf-8-*-
class
Foo
(
object
)
:
country
=
"china"
def
__init__
(
self
,
name
)
:
self
.name
=
name
def
f
(
self
)
:
print
"this is function f.name = "
,
self
.name
obj
=
Foo
(
"abc"
)
setattr
(
obj
,
"age"
,
19
)
#增加普通字段
setattr
(
obj
,
"show"
,
lambda
num
:
num
+
1
)
#增加普通方法
setattr
(
Foo
,
"tel"
,
"+086"
)
#增加靜態字段
print
obj
.age
print
Foo
.tel
print
obj
.show
(
10
)
|
執行結果
1
2
3
|
19
+
086
11
|
1.4.使用delattr動態的刪除類或者方法成員
演示代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#!/usr/bin/env python
# -*-coding:utf-8-*-
class
Foo
(
object
)
:
country
=
"china"
def
__init__
(
self
,
name
)
:
self
.name
=
name
def
f
(
self
)
:
print
"this is function f.name = "
,
self
.name
obj
=
Foo
(
"abc"
)
print
getattr
(
obj
,
"name"
)
delattr
(
obj
,
"name"
)
#刪除掉了對象的普通字段name
print
getattr
(
obj
,
"name"
)
print
getattr
(
Foo
,
"country"
)
delattr
(
Foo
,
"country"
)
#刪除掉類的靜態字段
print
getattr
(
Foo
,
"country"
)
#打印時說找不到些成員,報錯
|
執行結果
1
2
3
4
5
|
Traceback
(
most
recent
call
last
)
:
File
"D:/����/python/��������/day08/blog/fanshe.py"
,
line
17
,
in
<
module
>
abc
print
getattr
(
obj
,
"name"
)
AttributeError
:
'Foo'
object
has
no
attribute
'name'
|
二.在當前模塊中使用反射
獲取到對應的模塊.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/usr/bin/env python
# -*-coding:utf-8-*-
import
sys
data
=
"abc"
def
f1
(
)
:
print
"f1 function"
def
f2
(
)
:
print
"f2"
this_module
=
sys
.modules
[
__name__
]
print
hasattr
(
this_module
,
"data"
)
#使用反射
f1_get
=
getattr
(
this_module
,
"f1"
)
#使用反射獲取
f1_get
(
)
|
以上是反射對類,對象,模塊成員操作的基本方法.
三.使用字符串自動導入模塊
依據傳入的字符串,自動導入模塊.類似上文的方法反射
1
2
3
4
5
6
7
|
import
importlib
my_moudle_name
=
"lib.aa"
aa
=
importlib
.import_module
(
my_moudle_name
)
print
(
aa
)
print
(
aa
.C
(
)
.name
)
|
執行結果
1
2
|
<
module
'lib.aa'
from
'D:\\python\\day10\\lib\\aa.py'
>
ait24
|