博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面向对象进阶
阅读量:7124 次
发布时间:2019-06-28

本文共 4343 字,大约阅读时间需要 14 分钟。

isinstance(obj,cls)检查是否obj是否是类 cls 的对象

issubclass(sub, super)检查sub类是否是 super 类的派生类

反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。

hasattr(object,name)判断object中有没有一个name字符串对应的方法或属性

getattr(object, name, default=None),获取属性

setattr(x, y, v),创建属性

delattr(x, y),删除属性

为什么用反射之反射的好处

好处一:实现可插拔机制

有俩程序员,一个lili,一个是egon,lili在写程序的时候需要用到egon所写的类,但是egon去跟女朋友度蜜月去了,还没有完成他写的类,lili想到了反射,使用了反射机制lili可以继续完成自己的代码,等egon度蜜月回来后再继续完成类的定义并且去实现lili想要的功能。

总之反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

好处二:动态导入模块(基于反射当前模块成员)

 

类属性相关方法__setattr__,__delattr__,__getattr__

class Foo:    x=1    def __init__(self,y):        self.y=y    def __getattr__(self, item):        print('----> from getattr:你找的属性不存在')    def __setattr__(self, key, value):        print('----> from setattr')        # self.key=value #这就无限递归了,你好好想想        # self.__dict__[key]=value #应该使用它    def __delattr__(self, item):        print('----> from delattr')        # del self.item #无限递归了        self.__dict__.pop(item)#__setattr__添加/修改属性会触发它的执行f1=Foo(10)print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值f1.z=3print(f1.__dict__)#__delattr__删除属性的时候会触发f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作del f1.aprint(f1.__dict__)#__getattr__只有在使用点调用属性且属性不存在的时候才会触发f1.xxxxxx三者的用法演示

 

一个静态属性property本质就是实现了get,set,delete三种方法

class Foo:    @property    def AAA(self):        print('get的时候运行我啊')    @AAA.setter    def AAA(self,value):        print('set的时候运行我啊')    @AAA.deleter    def AAA(self):        print('delete的时候运行我啊')#只有在属性AAA定义property后才能定义AAA.setter,AAA.deleterf1=Foo()f1.AAAf1.AAA='aaa'del f1.AAA

应用

class Goods:    def __init__(self):        # 原价        self.original_price = 100        # 折扣        self.discount = 0.8    @property    def price(self):        # 实际价格 = 原价 * 折扣        new_price = self.original_price * self.discount        return new_price    @price.setter    def price(self, value):        self.original_price = value    @price.deleter    def price(self):        del self.original_priceobj = Goods()obj.price         # 获取商品价格obj.price = 200   # 修改商品原价print(obj.price)del obj.price     # 删除商品原价案例一

实例项相关方法__setitem__,__getitem,__delitem__

class Foo:    def __init__(self,name):        self.name=name    def __getitem__(self, item):        print(self.__dict__[item])    def __setitem__(self, key, value):        self.__dict__[key]=value    def __delitem__(self, key):        print('del obj[key]时,我执行')        self.__dict__.pop(key)    def __delattr__(self, item):        print('del obj.key时,我执行')        self.__dict__.pop(item)f1=Foo('sb')f1['age']=18f1['age1']=19del f1.age1del f1['age']f1['name']='alex'print(f1.__dict__)

 __str__,__repr__,__format__

改变对象的字符串显示__str__,__repr__

自定制格式化字符串__format__

#_*_coding:utf-8_*___author__ = 'Linhaifeng'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 __repr__(self):        return 'School(%s,%s)' %(self.name,self.addr)    def __str__(self):        return '(%s,%s)' %(self.name,self.addr)    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]        return fmt.format(obj=self)s1=School('oldboy1','北京','私立')print('from repr: ',repr(s1))print('from str: ',str(s1))print(s1)'''str函数或者print函数--->obj.__str__()repr或者交互式解释器--->obj.__repr__()如果__str__没有被定义,那么就会使用__repr__来代替输出注意:这俩方法的返回值必须是字符串,否则抛出异常'''print(format(s1,'nat'))print(format(s1,'tna'))print(format(s1,'tan'))print(format(s1,'asfdasdffd'))

__doc__查看类的描述信息

class Foo:    '我是描述信息'    passprint(Foo.__doc__)

__module__ 表示当前操作的对象在那个模块

__class__     表示当前操作的对象的类是什么

from lib.aa import Cobj = C()print obj.__module__  # 输出 lib.aa,即:输出模块print obj.__class__      # 输出 lib.aa.C,即:输出类

 __call__ 方法:对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:    def __init__(self):        pass        def __call__(self, *args, **kwargs):        print('__call__')obj = Foo() # 执行 __init__obj()       # 执行 __call__

 

转载于:https://www.cnblogs.com/roygood/p/9744472.html

你可能感兴趣的文章
Android 源码编译
查看>>
IE zoom:1 原理 以及应用
查看>>
C++单例模板
查看>>
tomcat html htm静态文件乱码utf-8的有关问题正文
查看>>
mysql规范
查看>>
jsp 练习 输入邮箱进行判断
查看>>
java的map.toString()后在前端js转成json格式
查看>>
ZigBee组网
查看>>
maven 项目出现 java.lang.ClassNotFoundException: or...
查看>>
PaperFoldMenuController
查看>>
JCMSegmentedPageController
查看>>
JSTokenField
查看>>
[应用模板]简洁优雅网站
查看>>
VCL篇:DevExpress v16.1新功能介绍
查看>>
iOS 之 CFBridgingRelease
查看>>
变量的存储类型
查看>>
使用AVAudioPlayer出现的问题
查看>>
封装性
查看>>
如何在适合OpenCart系统运行的美国服务器空间建立SMTP服务
查看>>
JAVA中int、String的类型转换
查看>>