python之反射

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

class Foo(object):

    pass

obj=Foo()

print(isinstance(obj,Foo))

>> 

True

 

  

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

class Foo(object):

    pass

class Bar(Foo):

    pass

print(issubclass(Bar,Foo))

>> 

True

  

反射的概念:指程序可以访问、检测和修改它本身2状态或行为的一种能力(自省)。

Python面向对象中的反射:通过字符串的形式操作对象相关的属性。Python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数

方法适用于类和对象(一切皆对象,类本身也是一个对象)

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

hasattr(object,name)查看对象的__dict__是否有这个值,返回bool值

检测是否含有某属性

格式:print(hasattr(x,y))

class People:

    country="China"

    def __init__(self,name):

        self.name=name

    def walk(self):

        print("%s is walking"%self.name)

p=People("karina")

print(hasattr(p,"name"))

>> 

True

  

gatattr 获取属性

格式:res=getattr(x,y)

print(res)

lass People:

    country="China"

    def __init__(self,name):

        self.name=name

    def walk(self):

        print("%s is walking"%self.name)

p=People("karina")

 

print(getattr(p,"name"))

>> 

karina

  

setattr 设置属性

格式:setattr(x,y,z)

print(x.__dict__)

class People:

    country="China"

    def __init__(self,name):

        self.name=name

    def walk(self):

        print("%s is walking"%self.name)

p=People("karina")

setattr(p,"age",18)#setattr(x,y,z)分别传入对象,属性,值

print(p.__dict__)

print(p.age)

 

#p.sex="female"  #设置一个性别

#print(p.sex) #打印

#print(p.__dict__)#查看对象对应字典中的信息

>> 

female

{'name': 'karina', 'sex': 'female'}#字典中已经添加性别这个键值对

  

delattr 删除属性

格式:delattr(x,y)

      Delattr(x,y1111)#不存在,则报错

      Print(x.__dict__)

class People:

    country="China"

    def __init__(self,name):

        self.name=name

    def walk(self):

        print("%s is walking"%self.name)

p=People("karina")

 

delattr(p,"name") #删除对象的name

# print(p.name)

print(p.__dict__)#查看对象对应的字典信息

>> 

{}

  

使用反射的好处

1.      实现可插拔机制

就是事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,其实是一种“后期绑定”,即事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

sever端调用FtpClient

2.动态导入模块(基于反射当前模块成员)

import sys #固定格式

def s1():

    print("s1")

def s2():

    print("s2")

this_module=sys.modules[__name__]# sys.modules[__name__]固定格式

 

print(hasattr(this_module,"s1"))

print(getattr(this_module,"s2"))

>> 

True

<function s2 at 0x015A41E0>

  

导入模块的推荐使用方法

import importlib

t=importlib.import_module("time")

print(t.time())

  

attr系列的使用

class Foo:

    def __init__(self,y):

        self.name=y

 

    def __setattr__(self, key, value):

        #为对象设置属性的时候,触发运行

        if not isinstance(value,str):#设置类型限制

            raise TypeError("must be str")

        self.__dict__[key]=value#添加到字典中

    def __delattr__(self, item):

        #删除属性

        print("delatter:%s"%item)

        self.__dict__.pop(item)#在字典中删除

    def __getattr__(self, item):

        #属性不存在的情况下才会触发

        print("getattr-->%s %s"%(item,type(item)))

 

f=Foo("egon")

f.age="18"

print(f.name)#在字典中查找

print(f.age)#在字典中查找

print(f.__dict__)

del f.name#删除字典中的name属性

print(f.__dict__)

f.xx

 

>> 

egon

18

{'name': 'egon', 'age': '18'}

delatter:name

{'age': '18'}

getattr-->xx <class 'str'>

  

二次加工(定义自己的数据类型)

二次加工使用继承的原理

class List(list):#继承list所有的属性

    def append(self,p_object):#子类定义派生的方法

        if not isinstance(p_object,int):#设置类型限制

            raise TypeError

        super().append(p_object)#继承父类

    def insert(self, index, p_object):

        if not isinstance(p_object,int):

            raise TypeError

        super().insert(index,p_object)

 

 

l=List([1,2])

print(l)

l.append(5)

print(l)

l.insert(0,52)

print(l)

>> 

[1, 2]

[1, 2, 5]

[52, 1, 2, 5]

  

授权:授权是包装的一个特性,包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原产品的功能,其他的则保持原样。授权的过程中,即是所有更新的功能是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

 

实现授权的关键点就是覆盖__getattr__方法

import time

class Open:

    def __init__(self,filepath,m="r",encode="utf8"):

        self.x=open(filepath,mode=m,encoding=encode)

        self.filepath=filepath

        self.mode=m

        self.encoding=encode

    def write(self,line):

        print("f自己的write",line)

        t=time.strftime("%Y-%m-%d %X")

        self.x.write("%s %s"%(t,line))

    def __getattr__(self, item):

        return getattr(self.x,item)

f=Open("b.txt","w")

 

f.write("123
")

f.write("123
")

f.write("123
")

f.write("123
")

f.write("123
")

>> 

2017-04-24 18:38:34 123

2017-04-24 18:38:34 123

2017-04-24 18:38:34 123

2017-04-24 18:38:34 123

2017-04-24 18:38:34 123

 

f=Open("b.txt","r+")

res=f.read()

print(res)

>> 

2017-04-24 18:38:34 123

2017-04-24 18:38:34 123

2017-04-24 18:38:34 123

2017-04-24 18:38:34 123

2017-04-24 18:38:34 123

  



原文地址:https://www.cnblogs.com/asaka/p/6758524.html