類的反射介紹和應用
阿新 • • 發佈:2019-01-31
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2018/5/20 23:27
# @Author : chen
# @File : 反射.py
"""
# 反射: 通過字串對映到物件的屬性
"""
"""
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def talk(self):
print('%s is talking' % self.name)
obj = People('egon', 18)
print(obj.name) # .(點)後面是一個屬性,不是字串,
# 本質上是 obj.__dict__['name'] 是隱藏字典裡key為'name'的值
print(obj.talk) # 點後面一定時一個屬性,不是字串
print(obj.talk())
# 接受使用者的輸入,使用input方法,接收內容都轉化為字串
# 需求,根據使用者輸入 返回物件的屬性
# choice = input('>>: ')
# print(obj.choice) # 會直接報錯(AttributeError:
# 'People' object has no attribute 'choice'),點後面應該是屬性,而不是字串
# 1.python 內建方法 hasattr,有兩個引數,第一個是物件,第二個是例項的屬性
# 只能返回True 和 False
print(hasattr(obj, 'name')) # 實際操作等於 obj.name 等同於 obj.__dict__['name']
print('attribute_talk', hasattr(obj, 'talk')) # obj.talk
print('attribute_talka', hasattr(obj, 'talka')) # obj.talk
# 2.getattr() 跟hasattr差不多,但不存在的屬性可以加引數不報錯
# 第一個,第二個引數跟hasattr一樣,第三個指定返回的結果(字串)
print(getattr(obj, 'talk', None)) # 當呼叫的是類的方法時,返回的結果是繫結類的方法的地址
# 如果是屬性就直接返回結果
print(getattr(obj, 'namexxxx', None))
print(getattr(obj, 'namexxxx', 'Error'))
# 3.以字串的形式 ,設定屬性(新增)
setattr(obj, 'sex', 'male') # obj.sex = 'male'
print(obj.sex)
# 4. 以字串形式 刪除屬性
delattr(obj, 'age') # obj.age
print(obj.__dict__)
"""
"""
class People:
country = 'China'
def __init__(self, name, age):
self.name = name
self.age = age
def talk(self):
print('%s is talking' % self.name)
obj = People('egon', 18)
# 5. 同時適用於類,判斷類中有沒有國籍這個屬性
print(getattr(People, 'country')) # People.country
# 通過字串,訪問物件,類的屬性
"""
# 反射的應用
# 接收使用者輸入,觸發查詢屬性
class Service:
def run(self):
while True:
inp = input('>>: ').strip() # cmd = 'get a.txt'
cmds = inp.split() # cmds = ['get', 'a.txt']
if len(cmds) == 2: # 判斷使用者輸入是否正確
if hasattr(self, cmds[0]):
# 這裡要使用self,不能隨便使用別的,我使用的Service,報錯了,就是因為傳參問題
func = getattr(self, cmds[0])
func(cmds[1])
else:
print('has no attribute')
else:
print('your cmds is wrong')
def get(self, cmds):
print('get......', cmds)
def put(self):
print('put......')
obj = Service()
obj.run()
getattr反射的使用
getattr(class,‘str’)
第一個引數填class,第二個使用的是字串(函式名)
另外一種用法
getattr(class,‘str’),第一個引數是模組名稱,第二個是類名
import sys
class Course:
def __init__(self, name, period, price):
self.name = name # 課程名
self.period = period # 課程週期
self.price = price # 課程價格
print('type型別:', type(sys.modules[__name__]), '值結果:', sys.modules[__name__])
s = getattr(sys.modules[__name__], 'Course')
print('s的type型別:', type(s))
a = s('egon', '6 months', 19800)
print('a的type型別:', type(a))
print('a的name屬性:', a.name)
輸出結果:
type型別: <class 'module'> 值結果: <module '__main__' from 'D:/python_product/select_homework/core/Teacher.py'>
s的type型別: <class 'type'>
a的type型別: <class '__main__.Course'>
a的name屬性: egon
==================================================================
sys.modules[__name__]
# 表示當前模組的名稱
雖然當前模組沒有類,但是使用了import後,將會把匯入模組的類放到當前模組的區域性變數中
於是,再獲取當前模組的類就會有了類名
使用反射就能獲取到對應的類,加括號即可執行