面向对象的反射机制
反射: 让对象告诉我们相关信息(对象拥有的属性和方法, 对象所属的类等....)
"""
# # 1). 如果知道对象拥有的属性和方法.
# print(dir(str))
# f = open('/tmp/passwd')
# print(dir(f))
# 2). 判断对象所属的类
# print(type('hello'))
class Student(object):
"""
这是student类的帮助文档
"""
def __init__(self, name, age):
self.name = name
self.__age = age
def get_score(self):
return "score"
def get_grade(self):
return 'grade'
s1 = Student("fentiao", 10)
print(type(s1))
print(isinstance(s1, Student))
print(isinstance('hello', Student))
# 3). 跟据对象可以获取的内容
print(s1.__class__)
print(s1.__dict__)
print(s1.__doc__)
# 4). hasattr, getattr, setattr, delattr
# hasattr: 判断对象是否包含对应的属性或者方法名;
print(hasattr(s1, 'name'))
print(hasattr(s1, '__age')) # 私有属性, 私有方法, 是不能判断的;
print(hasattr(s1, 'score'))
print(hasattr(s1, 'get_score'))
print(hasattr(s1, 'set_score'))
# getattr: 用于返回对象的属性值或者方法名对应的方法体;
print(getattr(s1, 'name'))
print(getattr(s1, '__age', 'no attr'))
print(getattr(s1, 'get_score', 'no method')) # 获取方法名, 如果要执行方法, 直接调用即可
print(getattr(s1, 'set_score', 'no method')) # 获取方法名, 如果要执行方法, 直接调用即可
# setattr:
# 修改某个属性的值
setattr(s1, 'name', 'westos')
print(getattr(s1, 'name'))
# 添加某个属性及对应的值;
setattr(s1, 'score', 100)
print(getattr(s1, 'score'))
# 修改方法
def get_score1():
return "这是修改的方法内容"
setattr(s1, 'get_score', get_score1)
print(getattr(s1, 'get_score')())
def set_score():
return "这是添加的方法"
# 添加方法
setattr(s1, 'set_score', set_score)
print(getattr(s1, 'set_score')())
# delattr
delattr(s1, 'name')
print(hasattr(s1, 'name'))
print(hasattr(s1, 'set_score'))
delattr(s1, 'set_score')
print(hasattr(s1, 'set_score'))
反射机制的应用场景_动态方法调用
https://www.csdn.net/nav/newarticles
https://www.csdn.net/nav/watchers
https://www.csdn.net/nav/news
https://www.csdn.net/nav/ai
https://www.csdn.net/bbs/newarticles
https://www.csdn.net/bbs/watchers
https://www.csdn.net/bbs/news
https://www.csdn.net/bbs/ai
"""
class Web(object):
def newarticles(self):
return "<h1>newarticles</h1>"
def watchers(self):
return "<h1>watchers</h1>"
def news(self):
return "<h1>news</h1>"
def ai(self):
return "<h1>ai</h1>"
flask = Web()
def run():
url = input("url:").split('/')[-1]
# if url == 'news':
# return flask.news()
# elif url == 'ai':
# return flask.ai()
# else:
# return "<h1>404</h1>"
if hasattr(flask, url): # ai
return getattr(flask, url)()
else:
return "<h1>404</h1>"
if __name__ == "__main__":
while True:
print(run())
反射机制与动态导入模块
lib/init
from lib.blog import *
from lib.bbs import *
lib/bbs
def login():
return 'login.html'
def logout():
return "logout.html"
def index():
return "bbsIndex.html"
lib/blog
def login():
return 'login.html'
def logout():
return "logout.html"
def index():
return "blogIndex.html"
# 动态导入模块
/bbs/login
/bbs/index
/blog/login
/blog/index
"""
def run():
# '/bbs/index' ; modules='bbs', func=‘index’
modules, func = input("url:").split('/')[-2:]
# 导入一个包含变量的模块名, 其中obj是模块的别名
obj = __import__('lib.'+ modules)
# 判断模块中是否有指定的方法, 如果有, 则执行代码, 如果没有, 404报错;
print(obj)
# print(modules)
# print(obj.index())
if hasattr(obj, func):
fun = getattr(obj, func)
return fun()
else:
return "404: 页面找不到"
# import lib.bbs
# import lib.bbs as obj
# obj.index()
# lib.bbs.index()
# if hasattr(flask, url): # ai
# return getattr(flask, url)()
# else:
# return "<h1>404</h1>"
if __name__ == "__main__":
while True:
print(run())
模块导入import理解
- 注意: import内置函数用于动态加载类和函数.
如果一个模块经常变化, 就可以使用import实现动态导入.
# import lib.bbs as obj
# print(obj.index())
obj = __import__('lib.bbs')
print(obj.index())