您的位置:首页 > 其它

假期(面向对象相关)

2018-02-14 12:12 239 查看
"""
一、isinstance(obj,cls) 和 issubclass(sub,super)
isinstance(obj,cls) 检查obj是否是类cls的对象
class Bar(object):
pass
class Foo(object):
pass
obj = Foo()
print(isinstance(obj,Foo))     #True
print(isinstance(obj,Bar))     #False
issubclass(sub,super) 检查sub类是否是super类的子类(派生类)
class Bar(object):
pass
class Foo(Bar):
pass
class Te(object):
pass
print(issubclass(Foo,Bar))    #True
print(issubclass(Te,Bar))     #False
"""
"""
二、反射:通过字符串的方式操作对象相关的属性,python中的一切事物都是对象,都可以使用反射
hasattr(object,name) 判断object中有没有一个name字符串对应的方法或者是属性
getattr(object,name,default=None)  从object中获取name属性,如果没有返回默认值None
setattr(obj,x,y) 给obj对象设置属性x=y
delattr(obj,x) 删除对象obj里的x属性
类也是对象,也可以有这四个方法
使用方法测试:
class Foo(object):
name = "我是你的什么啊?"
def __init__(self,addr):
self.addr = addr
obj = Foo("去你大爷的")
print(hasattr(obj,"name"))    #True
print(getattr(obj,"name"))    #我是你的什么啊?
setattr(obj,"sb",True)
print(obj.__dict__)           #{'addr': '去你大爷的', 'sb': True}
delattr(obj,"sb")
print(obj.__dict__)           #{'addr': '去你大爷的'}
反射当前模块成员:
import sys
def s1():
print("s1")
def s2():
print("s2")
this_module = sys.modules[__name__]
print(hasattr(this_module,"s1"))
使用反射的好处:
实现代码的可插拔机制;在导入模块方面经常使用反射;动态的导入模块

三、__setattr__,__delattr__,__getattr__;
#__setattr__添加/修改属性会触发它的执行
#__delattr__删除属性的时候会触发
#__getattr__只有在使用点调用属性且属性不存在的时候才会触发

四、二次加工标准类型(包装)
class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和mid
def append(self, p_object):
' 派生自己的append:加上类型检查'
if not isinstance(p_object,int):
raise TypeError('must be int')
super().append(p_object)        #调用父类的append方法
@property
def mid(self):
'新增自己的属性'
index=len(self)//2
return self[index]
实现授权的关键点就是覆盖__getattr__方法
import time
class FileHandle:
def __init__(self,filename,mode='r',encoding='utf-8'):
self.file=open(filename,mode,encoding=encoding)
def write(self,line):
t=time.strftime('%Y-%m-%d %T')
self.file.write('%s %s' %(t,line))

def __getattr__(self, item):
return getattr(self.file,item)

f1=FileHandle('b.txt','w+')
f1.write('你好啊')
f1.seek(0)
print(f1.read())
f1.close()

五、__getattribute__:
和__getattr__类似,不过不管是否存在都会执行
class Foo:
def __init__(self,x):
self.x = x
def __getattribute__(self, item):
print("我总会执行")
obj = Foo(10)
print(obj.x)
print(obj.xxx)
!当getattr和getattribute同事存在的时候只执行getattribute,除非抛出异常,两者一起执行

六、描述符(__get__,__set__,__delete__):
什么是描述符:描述符的本质就是一个新式类,在这个新式类中至少实现了__get__(),__set__(),__delete__()中的一个
这也被称为描述符协议
__get__():调用一个属性的时候触发
__set__():为一个属性赋值的时候触发
__delete__():删除属性的时候触发
class Foo:   #这个类称为描述符
def __get__(self, instance, owner):
pass
def __set__(self, instance, value):
pass
def __delete__(self, instance):
pass
描述符的作用:用来代理另外一个类的属性(必须把描述符定义为这个类的类属性,不能定义到构造方法中)
分类:
数据描述符:至少实现了__get__() 和__set__()方法
非数据描述符:没有实现__set__()方法
注意事项:
1、描述符本身应该定义为新式类,被代理的类也应该是新式类
2、必须定义为类属性,不能定义到构造函数中
3、要严格遵循优先级,优先级由高到低分别是(类属性,数据描述符,实例属性,非数据描述符,找不到的时候触发__getattr__())
描述符的使用:
描述符的总结:

六、property:
一个静态属性property本质就实现了get,set,delete三种方法
用法一:
class Foo:
@property
def AAA(self):
print("get的时候运行")
@AAA.setter
def AAA(self,value):
print("set的时候运行",value)
@AAA.deleter
def AAA(self):
print("delete 的时候运行")
obj = Foo()
obj.AAA  #get
obj.AAA = "aaa"   #set
del obj.AAA    #delete
用法二:
class Foo:
def get_AAA(self):
print("get的时候yunx")
def set_AAA(self,value):
print("set 的时候运行")
def delete_AAA(self):
print("delete的时候运行")
AAA=property(get_AAA,set_AAA,delete_AAA)    #内置的property三个参数必须与get,set,delete一一对应

七、__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 时执行")
def __delattr__(self, item):
print("del obj 执行,")
self.__dict__.pop(item)
obj = Foo("sb")
obj["age"] = 18
obj["age1"] = 19
del obj.age1
del obj["age"]
obj["name"] = "alex"
print(obj.__dict__)

八、__str__,__repr__,__format__:
改变对象的字符串显示__str__,__repr__,当你打印对象的时候假如里面没有这两个方法,那么打印出来的你是看不懂的
自定义格式化字符串:__format__
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
- 示例:
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 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)

print(format(s1,'nat'))
print(format(s1,'tna'))
print(format(s1,'tan'))
print(format(s1,'asfdasdffd'))

九、__slots__:
在类中写一个slots,在吧类中的某些字段写在里面,外部才可以访问,不写访问不到

十、__next__和__iter__实现迭代器协议
模拟实现range方法:
class Range:
def __init__(self,n,stop,step):
self.n=n
self.stop=stop
self.step=step

def __next__(self):
if self.n >= self.stop:
raise StopIteration
x=self.n
self.n+=self.step
return x

def __iter__(self):
return self

for i in Range(1,7,3): #
print(i)

十一、__doc__
- 显示描述信息,即注释信息
- 无法被继承

十二、__module__和__class__
- __module__  表示当前操作的对象在哪个摸快
- __class__表示当前操作的对象的类是什么

十三、__del__:
- 析构方法:当对象在内存中被释放时执行这段代码
- 比如在数据库链接中关闭数据库,文件操作中的close操作

十四、__enter__和__exit__:
__enter__在进来的时候执行
__exit__在出去的时候执行
- 对象调用前后执行这两个方法

十五、__call__方法:
- 对象后边+括号自动触发执行
- 构造方法的执行是由创建对象触发的,即对象=类名();而对于__call__方法是对象()或者类()()

十六、metaclass
exec:三个参数       字符串形式的命令  全局作用域  局部作用域
exec会在指定的局部作用域内执行字符串内的代码,除非明确地使用global关键字
- 类也是对象
- 什么是元类
- 元类是类的类,类的模板
- 元类是用来控制如何创建类的,正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为元类的实例化的结
果为我们用class定义的类,正如类的实例为对象(f1对象是Foo类的一个实例,Foo类是 type 类的一个实例)type是python的一
个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象
- 创建类的两张方式:
- 方式一:使用class关键字
- 方式二:手动模拟class创建类的过程
- 类名
- 类的父类
- 类体
#类名
class_name='Chinese'
#类的父类
class_bases=(object,)
#类体
class_body=
country='China'
"
def __init__(self,name,age):
self.name=name
self.age=age
def talk(self):
print('%s is talking' %self.name)
"
- 一个类没有声明自己的元类,默认它的元类就是type,除了使用元类type,用户也可以通过继承type俩自定义元类
- #元类控制类的实例化过程:
1 类(),调用元类.__call__()
2 在1的方法中调用:
类.__new__() #返回类的对象obj
类.__init__(obj,...) #为对象进行初始化

- 元类控制类本身的产生过程

"""
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: