1.面向对象的反射机制
反射: 让对象告诉我们相关信息(对象拥有的属性和方法, 对象所属的类等....) 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')) 获取方法名, 如果要执行方法, 直接调用即可 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'))
2.反射机制的应用场景-动态方法调用
https://www.youkuaiyun.com/nav/newarticles https://www.youkuaiyun.com/nav/watchers https://www.youkuaiyun.com/nav/news https://www.youkuaiyun.com/nav/ai https://www.youkuaiyun.com/bbs/newarticles https://www.youkuaiyun.com/bbs/watchers https://www.youkuaiyun.com/bbs/news https://www.youkuaiyun.com/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 hasattr(flask, url): return getattr(flask, url)() else: return "<h1>404</h1>" if __name__ == "__main__": while True: print(run())
3.反射机制与动态导入模块
动态导入模块 /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())
3.python异常处理
【1】常见异常
NameError print(a) IndexError: 索引错误 li = [1,2,3,4] print(li[8]) KeyError d = dict(a=1, b=2) print(d['f']) ZeroDivisionError: 除0错误 print(10/(2-2)) class Student(object): def __init__(self, name, age): self.name = name self.age = age def echo(self): print(self.name, self.age) AttributeError: 对象没有该属性 s1 = Student("westos", 10) print(s1.scores) s1.echo() s1.echo1() FileNotFoundError with open('/tmp/passwd9') as f: print(f.read(5)) 总结: 在程序运行过程中影响程序正常运行的内容, 称为异常.
【2】try......except......finally语句
捕获异常 try: f = open("hello.txt", 'w') f.write("这是一个测试文件") 注意: except语句不一定会执行, 只有在try语句中出现IOError报错时, 才会执行. except IOError as e: print(e) print("没有找到文件或者文件读取失败") 如果没有捕获到异常, 则执行else语句的内容 else: print("文件内容写入成功") 无论是否捕获到异常, 都执行的语句. finally: f.close() print("文件已经关闭") f = open("hello.txt", 'w') f.write("这是一个测试文件")
【3】不指定异常的except的使用
try:
f = open('hello.txt')
f.write("这是一个测试文件")
f.read()
不建议捕获所有的异常, 因能不能定位错误的位置.
except:
print("捕获所有的异常....")
else:
print("如果没有捕获到异常, 执行else语句")
finally:
f.close()
print("有异常或者没有异常都会执行")
【4】捕获多个异常
捕获异常 try: f = open("hello.txt", 'w') f.write("这是一个测试文件") 注意: except语句不一定会执行, 只有在try语句中出现IOError报错时, 才会执行. except IOError as e: print(e) print("没有找到文件或者文件读取失败") 如果没有捕获到异常, 则执行else语句的内容 else: print("文件内容写入成功") 无论是否捕获到异常, 都执行的语句. finally: f.close() print("文件已经关闭") f = open("hello.txt", 'w') f.write("这是一个测试文件") try: f = open('hello.txt') f.write("这是一个测试文件") f.read() 不建议捕获所有的异常, 因能不能定位错误的位置. except: print("捕获所有的异常....") else: print("如果没有捕获到异常, 执行else语句") finally: f.close() print("有异常或者没有异常都会执行") 异常处理 assert(断言): NameError, KeyError try: d = dict(a=1, b=2) print(d['f']) # KeyError print(a) # NameError except KeyError as e: print(e) except NameError as e: print(e) else: print("没有产生异常") finally: print("无论是否产生异常的清理操作") print("new start")
运行结果:
【5】抛出异常-触发异常
raise: 关键字, 用来抛出异常. raise 抛出异常的名称, 抛出异常的详细显示 def get_age(age): if 0 < age <= 200: print(age) else: 如果raise抛出异常, 程序后面的代码不会再执行. raise Exception('invaild age') get_age(1000) get_age(100) 自定义异常类 所有的异常实际上是一个类, 所以异常的父类都是BaseException. IOError, IndexError, KeyError, FileExistsError class AgeError(BaseException): pass def get_age(age): if 0 < age <= 200: print(age) else: 如果raise抛出异常, 程序后面的代码不会再执行. raise AgeError('invaild age') get_age(1000) get_age(100)
【6】抛出异常与继承
class B(Exception): pass class C(B): pass class D(C): pass for cls in [B, C, D]: try: 抛出异常 raise cls() except D: print("D") except C: print("C") except B: print("B")
【7】断言
raise:
age = int(input('Age:'))
assert 1 == 1
assert 1 != 1
assert 0 < age < 100, "年龄不合法"
if 1!=1:
raise AssertionError
def is_huiwen_num(num):
snum = str(num)
return snum == snum[::-1]
如果希望程序中的所有assert语句不执行, 那么给python -O 脚本名
if __name__ == "__main__":
assert is_huiwen_num(100) == True, "error"
assert is_huiwen_num(101) == True
print("assert")
import unittest
【8】logging模块
import logging
s = '0'
n = int(s)
配置日志的信息:
1). 日志级别: debug, info, warning, error, critical
2). level: 指日志级别为info及以上的日志信息会被记录到文件中;
3). format: 指定日志的格式, 可以去logging.Formatter查看参考信息
logging.basicConfig(filename="hello.log",level=logging.INFO,
format="%(asctime)s - %(filename)s[%(lineno)d] - %(levelname)s: %(message)s")
logging.debug("this is a debug info")
logging.info("this is a info")
logging.warning("这是一条警告信息")
logging.info('n=%d' %n)
print(10/n)