python进阶-面向对象编程三:类和对象的反射方法

类的内置方法:__getattr__,__setattr__,__delattr__

# __getattr__为内置方法,当使用点号[获取实例属性时],如果属性不存在就自动调用__getattr__方法,如类Foo()的对象f.name
# __setattr__当[设置类实例属性时]自动调用,如f.name=5 就会调用__setattr__方法  self.[name]=5
# 这个类是从dict继承来的,是dict的超类

class Foo:
    def __init__(self,name):
        self.name=name


    def hello(self):
        print("hello")

    #获取实例属性时,属性不存在的情况自动调用
    def __getattr__(self, item):
        # 打印属性不存在时的属性和类型
        print("%s %s"%(item,type(item)))


    # 当[设置类实例属性时]自动调用
    def __setattr__(self, key, value):
        print(self,key,value)

        if not isinstance(value,str):
            raise TypeError("must be str")
        else:
            self.__dict__[key]=value

    def __delattr__(self, item):
        self.__dict__.pop()



f=Foo("adamanter")
f.hello()
f.name  #类有这个属性,不会调用__getattr__
f.food  #类没有这个属性,会调用__getattr__,显示food <class 'str'>,属性是food,类型是str
f.eat   #类没有这个属性,会调用__getattr__,显示eat <class 'str'>,属性是eat,类型是str
f.name = "antonio"  #设置调用__setter__,打印本身<__main__.Foo object at 0x1011bff28> name antonio,也放入了f字典
#f.age =18 #报错,因为不符合设置属性时候,我们判断的是必须是字符串,因此抛出:must be str
print(Foo.__dict__)  #里面有hello函数
print(f.__dict__)    #里面有{'name': 'adamanter'}
# {'__setattr__': <function Foo.__setattr__ at 0x10842fbf8>, '__init__': <function Foo.__init__ at 0x10842fae8>,
#  '__getattr__': <function Foo.__getattr__ at 0x10842fb70>, '__dict__': <attribute '__dict__' of 'Foo' objects>,
# '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__delattr__': <function Foo.__delattr__ at 0x10842fc80>,
# '__doc__': None, 'hello': <function Foo.hello at 0x10842fa60>, '__module__': '__main__'}
# {'name': 'adamanter'}

  


python面向对象中的反射:hasattr,getattr,setattr,delattr

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

# 四个可以实现自省的函数
# 下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

# 基于类的反射
class People:
    country="china"
    def __init__(self,name):
        self.name=name

    def walk(self):
        print("%s walk",self.name)

h=People("ada")
# 利用布尔值返回类或对象有没有这个属性,hasattr返回布尔值
print(hasattr(People,"country"))
print(hasattr(h,"country"))
print(hasattr(h,"walk"))
# True
# True
# True

#获取类或对象的某个属性,getattr回值就是获取的属性值或绑定的方法
res1=getattr(People,"country")
print(res1)
res2=getattr(h,"country")
print(res2)
res3=getattr(h,"walk")
print(res3)
# china
# china
# <bound method People.walk of <__main__.People object at 0x10f7e75f8>>


#设置类或对象的某个属性并查看,setattr返回None,但是属性已经添加
sss = setattr(h,"age",18)
print(sss)
print(h.__dict__)
# None
# {'name': 'ada', 'age': 18}


#删除类或对象的某个属性并查看,delattr返回None,但是属性已经删除
ddd = delattr(h,"age")
print(ddd)
print(h.__dict__)
# None
# {'name': 'ada'}  因为没有age属性,不可修改属性

  

基于模块的反射

# 反射当前模块的属性
import sys
x=1111
class Foo:
    pass

def s1():
    print('s1')
def s2():
    print('s2')

this_module=sys.modules[__name__]
print(this_module)
# <module '__main__' from '/Users/Alex/PycharmProjects/hellotest/python/反射.py'>

#这句话所做的操作:遍历s1在不在this_module 的字典__dict__中
print(hasattr(this_module,'s1'))
print(getattr(this_module,'s2'))
print(this_module.s1)
print(this_module.s2)
# True
# <function s2 at 0x101678f28>
# <function s1 at 0x1014a0f28>
# <function s2 at 0x101678f28>






# import importlib
# t=importlib.import_module("time")
# print(t.time())

#导入当前路径下包impag下的hello.py
# x=importlib.import_module("impag.hello")


# 字符串导入模块,官方不推荐
# m=input("please input your module:")
# m1=__import__(m)
# print(m1)
# print(m1.time())

  

重写自定制列表的append和insert方法

class List(list):
    def append(self,object:str):
        if not isinstance(object,int):
            raise TypeError("must int")
        super().append(object)

    def insert(self, index: int, object):
        if not isinstance(object,int):
            raise TypeError("must int")
        super().insert(index,object)


l=List([1,2,3])
print(l)
# [1, 2, 3]
l.append(4)  #会调用类本身的append方法
print(l)
# [1, 2, 3, 4]

# l.append("hello")  我们重写了append方法,要求他只能接受int
# raise TypeError("must int")

l.insert(0,-1)  #第一个0是索引,必需是int,第二个规定是int
# l.insert(0,"hello")  #报错,因为我们重写了增加和插入方法,非int类型插入报错,必须是int类型
print(l)
# [-1, 1, 2, 3, 4]

  

 

posted @ 2017-09-13 19:23  Adamanter  阅读(122)  评论(0编辑  收藏  举报