Python——面向对象的深入理解

xiaoxiao2021-03-01  12

一 类方法与静态方法 类内部的装饰器

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实现动态导入.

转载请注明原文地址: https://www.6miu.com/read-4050323.html

最新回复(0)