反射与常用模块
反射与常用模块
一、反射
1.反射的定义:把一个字符串数据类型的变量变成一个真实存在的变量名,并且能够使用它
2.getattr是反射的灵魂,与hasattr是最佳cp:
(1)类名调属性或方法(静态(类)属性,静态方法和类方法)
class SB: def __init__(self,name): self.name = name def happy(self,x): print('sb %s is happy'%self.name) return x+'aaaaaa' jinghong = SB('景弘') func = getattr(jinghong,'happy') if hasattr(jinghong,'sleep'): func = getattr(jinghong,'sleep') func()
(2)对象名调属性或方法(对象属性,普通方法(self))
class Login(): r = 'Person' @staticmethod def login(): print('login') @staticmethod def register(): print('register') obj.attr -- getattr(obj,'attr') obj.func() -- getattr(obj,'func') print(hasattr(Login,'login')) func = getattr(Login,'login') func() getattr(Login,'login')()
(3)模块名调用属性或方法(变量,函数)
import my_module getattr(my_module,'jinghong_sb')() print(getattr(my_module,'xiaoyueyue')) xiaoxuanxuan = 2222 import sys print(sys.modules[__name__]) print(getattr(sys.modules[__name__],'xiaoxuanxuan'))
(4)在自己模块中调用属性或方法(变量,函数),
自己的模块:sys.modules[__name__]
def login(): print('login') def register(): print('register') f = input('func >>> ') import sys getattr(sys.modules[__name__],f)()
3.setattr
4.delattr
class SB: def __init__(self,name): self.name = name def happy(self,x): print('sb %s is happy'%self.name) return x+'aaaaaa' jinghong = SB('景弘') # jinghong.sex = None # 'sex' setattr(jinghong,'sex','female') print(jinghong.sex) # jinghong.name def sleep(jinghong): print('%s is sleeping'%jinghong.name) setattr(jinghong,'sleep',sleep) jinghong.sleep(jinghong) print(jinghong.happy('a')) delattr(jinghong,'sex') print(jinghong.sex)
二、常用模块
1.hashlib模块:摘要算法,单向的,只能摘要成密文不能反解,对于长字符串分次update与一次update的数据相同
(1)检测文件一致性:文字文件,逐行读;视频图片文件,按字节读
import hashlib import os filesize = os.path.getsize('文章') f = open('文章','rb') md5_obj = hashlib.md5() while filesize > 0 : readsize = 10 if filesize>10 else filesize content = f.read(readsize) md5_obj.update(content) filesize -= readsize print(md5_obj.hexdigest())
(2)存储密文密码:会有暴力破解(撞库)的行为,故需‘加盐’的过程
# f = open('userinfo','w') # md5 = hashlib.md5() # md5.update(b'3714') # md5_value = md5.hexdigest() # f.write('alex|%s\n'%md5_value) # f.close() pwd = input('pwd : ') f = open('userinfo') alex_info = f.readline().strip() user,passwd = alex_info.split('|') md5 = hashlib.md5(b'salt') md5.update(bytes(pwd,encoding='utf-8')) print(md5.hexdigest()) if passwd == md5.hexdigest(): print('登录成功')
2.logger模块
import logging logging.basicConfig(level=logging.warning, format = '%(asctime)s [%(lineno)d] %(message)s', datefmt='%y/%m/%d %H:%M:%S', filename='test.log', filemode='a') logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')
def log(filename): logger = logging.getLogger() logger.setLevel(logging.DEBUG) fh = logging.FileHandler(filename,encoding='utf-8') formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) sh = logging.StreamHandler() formatter2 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') sh.setFormatter(formatter2) logger.addHandler(sh) return logger logger = log('log') logger.debug('debug hello') logger.warning('你好')
3.configparser模块
import configparser config = configparser.ConfigParser() config.read('example.ini') import configparser config = configparser.ConfigParser() config.read('example.ini') config.add_section('yuan') config.remove_section('bitbucket.org') config.remove_option('topsecret.server.com',"forwardx11") config.set('topsecret.server.com','k1','11111') config.set('yuan','k2','22222') config.write(open('new2.ini', "w")) print(config.sections()) print(config['DEFAULT']['Compression']) if 'bitbucket.org' in config: print(config['bitbucket.org']) for i in config['bitbucket.org']: print(i) ret = config.get('bitbucket.org','age') print(ret) for k,v in config.items('bitbucket.org'): print(k,v) config["DEFAULT"] = {'age': '45', 'Compression': 'yes', 'CompressionLevel': '9', 'ForwardX11':'yes' } config['bitbucket.org'] = {'User':'hg'} config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} with open('example.ini', 'w') as configfile: config.write(configfile)
三、内置函数
1.其它的函数-内置函数-类的内置方法
(1)len
class SB: def __init__(self,name,sex): self.name = name self.sex = sex def __len__(self): return jiangyi = SB('jiangyi','male') print(jiangyi.__dict__) print(len(jiangyi))
(2)__format__:自定义格式化字符串
format_dict={ 'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型 'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址 'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名 } class School: def __init__(self,name,addr,type): self.name=name self.addr=addr self.type=type def __payment__(self): pass def payment(obj): obj.__payment__() len([12,3,4]) [1,2,3].__len__() def __format__(self, format_spec): # if format_spec if not format_spec or format_spec not in format_dict: format_spec='nat' fmt=format_dict[format_spec] print('fmt : %r'%fmt) return fmt.format(obj=self) s1=School('oldboy1','北京','私立') s1.__format__('nat') print(format(s1,'nat')) print(format(s1,'tna'))
(3)format
class Sb(): def __init__(self,name,sex): self.name = name self.sex = sex liquan = Sb('liquan',None) print('{name} {sex}'.format(**{'name':'liquan','sex':None})) print('{obj.name} {obj.sex}'.format(obj = liquan))
(4)__str__、__repr__:改变对象的字符串显示
class Animal: def __init__(self,kind,name): self.kind = kind self.name = name def __str__(self): return 'str : %s : %s'%(self.kind,self.name) def __repr__(self): return 'repr : %s : %s'%(self.kind,self.name) cat = Animal('cat','guolei') # print('%s'%cat) print(str(cat)) print(repr(cat)) print('%s'%cat) print('%r'%cat)
(5)__call__:对象后面加括号,触发执行,构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后
加括号触发的,即:对象() 或者 类()()
__eq__、__hash__:对象后面加括号,触发执行
__del__:析构方法,当对象在内存中被释放时,自动触发执行;析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
class Animal: def __init__(self,kind,name): self.kind = kind self.name = name def __call__(self, *args, **kwargs): print('call 方法正在执行') # def __del__(self): # print('del 被执行了') def __eq__(self, other): if self.name == other.name and self.kind == other.kind: return True else: return False def __hash__(self): return hash(self.name) cat = Animal('cat','guolei') dog = Animal('cat','guolei') print(dog == cat) #__eq__ print(hash(cat)) #__hash__
(6)item系列
class Animal: def __init__(self,name): self.name = name def __getitem__(self, item): return getattr(self,item) def __setitem__(self, key, value): setattr(self,key,value) def __delitem__(self, key): delattr(self,key) cat = Animal('guolei') # cat.name print(cat['name']) #getitem cat['sex'] = '公' #setitem print(cat.sex) print(cat['sex']) del cat['name'] print(cat.name)
(7)单例模式(__new__):实例始终只有一个,它的属性可以随着你的改变而改变
class A: def __init__(self): self.x = 1 print('in init function') def __new__(cls, *args, **kwargs): print('in new function') return object.__new__(A, *args, **kwargs) a = A()
class Teacher: #创建一个老师类 __isinstance = None #创建一个私有静态变量来装裸着的对象 def __new__(cls, *args, **kwargs): #创建一个裸着的对象 if not cls.__isinstance: #如果__isinstance属性为None cls.__isinstance = object.__new__(cls) #用object.__new__创建一个裸着的对象 return cls.__isinstance #返回一个对象 def __init__(self,name,cloth): #self就是cls.__isinstance返回的对象 self.name = name #给self的name属性赋值 self.cloth = cloth #给self的cloth属性赋值 刘老师 = Teacher('刘永熹','白色') print(刘老师.name) 王老师 = Teacher('王庆帅','黑色') 王老师2 = Teacher('王庆帅','黑色') 王老师3 = Teacher('王庆帅','黑色') 王老师4 = Teacher('王庆帅','黑色') print(刘老师.name) print(王老师) print(王老师2) print(王老师3) print(王老师4)
四、例子
1.纸牌游戏
class FranchDeck: ranks = [str(n) for n in range(2,11)] + list('JQKA') suits = ['红心','方板','梅花','黑桃'] def __init__(self): self._cards = [Card(rank,suit) for rank in FranchDeck.ranks for suit in FranchDeck.suits] def __len__(self): return len(self._cards) def __getitem__(self, item): return self._cards[item] def __setitem__(self, key, value): self._cards[key] = value deck = FranchDeck() print(deck[0].rank,deck[0].suit) from random import choice,shuffle print(choice(deck)) shuffle(deck) print(deck[0].rank,deck[0].suit)
2.
class Person: def __init__(self,name,age,sex,weight): self.name = name self.sex = sex self.age = age self.weight = weight 假设有100个person的对象, 若两个对象的obj1,obj2的name和sex属性相同 即obj1.name==obj2.name and obj1.sex==obj2.sex 我们认为两个对象为同一个对象,已知一个列表中的100个对象,对这100个对象进行去重。 提示: 重写Person类重的两个内置方法 class Person: def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age def __hash__(self): return hash(self.name+self.sex) def __eq__(self, other): if self.name == other.name and self.sex == other.sex: return True obj_lst = [] for i in range(100): obj_lst.append(Person('liquan','male',i)) print(obj_lst) print(set(obj_lst))
3.issubclass和isinstance
from collections import Iterable print(isinstance(range(10),Iterable)) print(isinstance(10,int)) #type(10) is int class Foo(object):pass obj = Foo() print(isinstance(obj, Foo)) print(isinstance(obj, object)) class A: pass print(issubclass(Foo,(object,A)))

浙公网安备 33010602011771号