一 类方法与静态方法
类内部的装饰器
class Date(object):
def __init__(self, year, mouth, day):
self.year = year
self.mouth = mouth
self.day = day
# echo普通用法,默认情况下会传递对象给echo
def echo(self):
return '%s %s %s' % (self.year, self.mouth, self.day)
# 默认传递类本身给的方法
@classmethod
def as_string(cls, s):
print(cls)
year, mouth, day = s.split('/')
d = cls(year, mouth, day)
return d
# 默认python解释器不会传递任何参数
@staticmethod
def is_vaild(s):
# 批量将年月日转换为整形
year, mouth, day = [int(i) for i in s.split('/')]
return 0 < mouth <= 12 and 0 < day <= 31 and 1 < year < 9999
s = '2018/4/22'
print(Date.is_vaild(s))
d = Date(2018, 12, 12)
print(d.is_vaild('2018/5/23')) # 这种方法形式是错误的,判断的是字符串中的内容
用来判断日期是否合格
二 with语句
上下文管理协议:
1)当with语句开始运行的时候,执行什么方法
2)当with语句结束的时候,触发的方法
class my_open(object):
def __init__(self, filename, mode='r'):
self._filename = filename
self._mode = mode
# 当with语句开始运行的时候,执行什么方法
def __enter__(self):
self.f = open(self._filename, self._mode)
return self.f
# 当with语句结束的时候,触发的方法
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
# 可以查看,但是不能更改
@property
def filename(self):
return self._filename
@property
def mode(self):
return self._mode
with my_open('/etc/passwd')as f:
print(f.closed)
print(f.read(5))
print(f.closed)
自己定义一个open类,俩实现上下文管理with语句
三 面向对象的反射机制
1) 如何知道对象拥有的属性和方法
print(dir(str))
f = open('/etc/passwd')
print(dir(f))
2) 判断对象所属的类
print(type('hello'))
class Student(object):
"""正义永远不会迟到!"""
def __init__(self, name, age):
self.__name = name
self.age = age
def play(self):
return 'lol'
def eat(self):
return 'fish'
s1 = Student('westos', 10)
print(type(s1))
print(isinstance(s1, Student))
print(isinstance('hello', Student))
3) 根据对象可以获取的内容
print(s1.__dict__)
print(s1.__class__)
print(s1.__doc__)
4) hasattr, getattr, setattr, delattr
hasattr:判断属性或者方法有没有
print(hasattr(s1, 'age'))
print(hasattr(s1, 'score'))
print(hasattr(s1, '__name')) # 私有属性或方法是不能判断的
print(hasattr(s1, 'play'))
print(hasattr(s1, 'get'))
getattr:用于返回对象的属性值或方法名对应的方法体
print(getattr(s1, 'age'))
print(getattr(s1, '__name', 'no attr'))
print(getattr(s1, 'play')) # 获取方法名,如果要执行,直接调用,加上()即可
print(getattr(s1, 'eat')())
setattr:修改
# 修改某个属性
print(getattr(s1, 'age'))
setattr(s1, 'age', '9999')
print(getattr(s1, 'age'))
# 添加某个属性及对应的值
setattr(s1, 'score', 100)
print(getattr(s1, 'score'))
# 修改方法
def play1():
return '这是修改的方法'
setattr(s1, 'play', play1)
print(getattr(s1, 'play')())
def append():
return '这是添加的方法'
setattr(s1, 'append', append)
print(getattr(s1, 'append')())
delattr:删除
delattr(s1, 'age')
print(hasattr(s1, 'age'))
print(hasattr(s1, 'append'))
delattr(s1, 'append')
print(hasattr(s1, 'append'))
四 反射机制的应用场景
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())
五 反射机制与动态导入模块
在本目录中建立新的目录:写入需要导入的模块
其中在init中写入:
from lib.bbs import *
from lib.blog import *
这样就可动态导入模块了
def run():
# '/bbs/login' modules='bbs' func='login'
modules, func = input('url:').split('/')[-2:]
# 导入一个包含变量的模块名,其中obj是模块的别名
obj = __import__('lib.%s'%(modules))
if hasattr(obj, func):
fun = getattr(obj, func)
return fun()
else:
return '404 error'
if __name__ == '__main__':
while True:
print(run())
注意: import内置函数用于动态加载类和函数.
如果一个模块经常变化, 就可以使用import实现动态导入.