python 面向对象编程 之 反射

1 什么是反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

 

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

四个可以实现自省的函数

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

 

四个方法的使用演示
class BlackMedium: feature='Ugly' def __init__(self,name,addr): self.name=name self.addr=addr def sell_house(self): print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name) def rent_house(self): print('%s 黑中介租房子啦,傻逼才租呢' %self.name) b1=BlackMedium('万成置地','回龙观天露园') #检测是否含有某属性 print(hasattr(b1,'name')) print(hasattr(b1,'sell_house')) #获取属性 n=getattr(b1,'name') print(n) func=getattr(b1,'rent_house') func() # getattr(b1,'aaaaaaaa') #报错 print(getattr(b1,'aaaaaaaa','不存在啊')) #设置属性 setattr(b1,'sb',True) setattr(b1,'show_name',lambda self:self.name+'sb') print(b1.__dict__) print(b1.show_name(b1)) #删除属性 delattr(b1,'addr') delattr(b1,'show_name') delattr(b1,'show_name111')#不存在,则报错 print(b1.__dict__)

 

 

 

 

#类也是对象

class Foo(object):
 
    staticField = "old boy"
 
    def __init__(self):
        self.name = 'wupeiqi'
 
    def func(self):
        return 'func'
 
    @staticmethod
    def bar():
        return 'bar'
 
print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')
print getattr(Foo,'bar')()#注意有什么不同




#反射当前 模块成员
import sys def s1(): print 's1' def s2(): print 's2' this_module = sys.modules[__name__] hasattr(this_module, 's1') getattr(this_module, 's2')
new_method_s2=getattr(this_module,'s2')#相当于给函数起了个别名
new_method_s2()
s2()#输出结果相同

导入其他模块,利用反射查找该模块是否存在某个方法
 
 
#!/usr/bin/env python
# -*- coding:utf-8 -*-

def test():
    print('from the test')

#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""
程序目录:
module_test.py
index.py

当前文件:
index.py
"""

import module_test as obj

#obj.test()

print(hasattr(obj,'test'))

getattr(obj,'test')()


反射的好处:
  1.实现可插播机制
  2.动态导入模块#--------------------------------


__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 = 3
print(f1.__dict__)

# __delattr__删除属性的时候会触发
f1.__dict__['a'] = 3 # 我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__)

# __getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx


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)

@property
def mid(self):
'新增自己的属性'
index = len(self) // 2
return self[index]


l = List([1, 2, 3, 4])
print(l)
l.append(5)
print(l)
# l.append('1111111') #报错,必须为int类型

print(l.mid)

# 其余的方法都继承list的
l.insert(0, -123)
print(l)
l.clear()
print(l)
 
 

class List(list):
def __init__(self, item, tag=False):
super().__init__(item)
self.tag = tag

def append(self, p_object):
if not isinstance(p_object, str):
raise TypeError
super().append(p_object)

def clear(self):
if not self.tag:
raise PermissionError
super().clear()


l = List([1, 2, 3], False)
print(l)
print(l.tag)

l.append('saf')
print(l)

# l.clear() #异常

l.tag = True
l.clear()

# 练习(clear加权限限制)


















转载于:https://www.cnblogs.com/yanxiatingyu/p/9323927.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值