反射,包装,授权

本文详细解析了Python中的反射机制,包括hasattr、getattr、setattr和delattr等函数的使用,以及isinstance与type的区别。同时,介绍了如何通过反射操作类和模块的属性,展示了包装和授权的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

isinstance和type区别

type() 不会认为子类是一种父类类型,不考虑继承关系。 
isinstance() 会认为子类是一种父类类型,考虑继承关系。
例如:
class A:
    pass
class B(A):
    pass
print(isinstance(A(),A))		#True
print(type(A()) == A)		#True
print(isinstance(B(),A))		#True
print(type(B()) == A)		#False
如果要判断两个类型是否相同推荐使用 isinstance()

issubclass() 方法用于判断参数 class 是否是类型参数 classinfo 的子类
issubclass(class, classinfo)

反射

通过字符串的形式操作对象的相关属性,python中的一切事物皆对象(都可以使用反射)

hasattr(obj,'name')   ---->obj.name
getattr(obj,'name',default='错误')   ---->obj.name     (如果没找到就返回default的值)
setattr(obj,'name',name)   ---->obj.name = name
delattr(obj,'name')  ---->del obj.name

python一切皆对象,类和模块也可以使用反射

import sys
obj = sys.modules[__name__]     #获取当前模块名
class BlackMedium:
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr

    def rent_house(self):
        print('[%s] 正在租房子'.format(self.name))

b1 = BlackMedium('万成置地','天露园')
#b1.name---->b1.__dic__['name']
print(b1.__dict__)

print(hasattr(b1,'name'))
print(hasattr(b1,'haha'))   #没有返回False

print(getattr(b1,'name'))
print(getattr(b1,'rent_house'))
func = getattr(b1,'rent_house')
func()
#自定义default
print(getattr(b1,'nameaa','没有该属性'))

#修改,没有则添加(可以作用在函数)
setattr(b1,'haha','F')
setattr(b1,'name','A')
setattr(b1,'func',lambda x:x+1)
setattr(b1,'func2',lambda self:self.name+'sb')
print(b1.__dict__)
print(b1.func(10))
print(b1.func2(b1))

#删除
delattr(b1,'name')
print(b1.__dict__)

类的内置attr属性(实例用的才会触发)

class Foo:
    x = 1
    def __init__(self,y):
        self.y = y

    #属性不存在时会自动触发 __getattr__
    def __getattr__(self, item):
        print('你找的属性 [%s] 不存在'%item)

    #删除属性时会触发 __delattr__
    # def __delattr__(self, item):
    #     # del self.item    #无限递归
    #     self.__dict__.pop(item)
    #
    # #设置属性时会触发 __setattr__
    # def __setattr__(self, key, value):
    #     print('__setattr__执行')
    #     # self.key = value    #这会造成无限递归
    #     self.__dict__[key] = value  #应该使用它

# f1 = Foo(10)
# print(f1.__dict__)
# f1.z = 2
# print(f1.__dict__)
# del f1.y    # 会调用 __delattr__ (类内置函数)
# del f1.x

f1 = Foo(10)
print(f1.y)
print(f1.name)      # item 是 name
getattribute(实例 . 调用都先调用此方法,之后根据情况在该方法下调用其他方法)
class Foo:
    def __init__(self,x):
        self.x = x

    def __getattr__(self, item):
        print('执行的是getattr')

    #实例  .调用都先调用 __getattribute__ ,当遇见 raise AttributeError 时调用 __getattr__
    def __getattribute__(self, item):
        print('执行的是getattribute')
        raise AttributeError('抛出异常')    #调用__getattr__ 方法

f1 = Foo(10)
f1.xxxxx   
getitemsetitmedelitem
f1 = Foo()
print(f1.age)		#调用的是 __getattr__
print(f1['age'])		#调用的是 __getitem__
f1.name = 'aa'		#调用的是  __setattr__
f1['name'] = 'aa'	#调用的是 __setitem__
del f1.name		#调用的是 __delattr__
del f1['name']		#调用的是 __delitem__
总结:   用 . 调用是 __getattr__ ; 用 [] 调用是 __getitem__ 

包装

#通过继承和派生完成包装
class List(list):
    def append(self, p):
       if type(p) is str:
           super().append(p)
    def show_middle(self):
        mid_index = int(len(self)/2)
        return self[mid_index]


# l1 = list("hello world")
# print(l1,type(l1))

l2 = List("hello world1")
print(l2,type(l2))
print(l2.show_middle())
l2.append(11)
l2.append('hh')
print(l2)

授权

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

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 %X')
    #     self.file.write('%s %s'%(t,line))

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


f1 = FileHandle('a.txt','w')
f1.write('1112\n')
f1.write('2222\n')
#f1.seek(0)
#print(f1.read())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值