类特殊属性魔法方法反射

概述

运行时,区别于编译时,指的是程序被加载到内存中执行的时候
反射,reflection,指的是运行时获取类型定义信息
一个对象能够在运行时,像照镜子一样,反射出其类型信息
简单说,在python中,能够通过一个对象,找出其type、class、attribute或method的能力,称为反射或者自省。
具有反射能力的函数有:type()、isinstance()、callable()、dir()、getattr()

反射相关的函数和方法

需求
有一个Point类,查看它实例的属性,并修改它。动态为实例增加属性

getattr(object,name[,default])

  • 通过name返回object的name属性,当name属性不存在,将使用default返回,如果没有default,则抛出AttributeError
  • name必须是字符串类型
  • default是函数,因为getattr返回的就是一个函数,因此当找不到name对应的函数后就调用default函数。

setattr(object,name,value)

  • object存在name属性时,则通过value覆盖之前name属性
  • object不存在name属性时,则新增属性
  • name依然时字符串类型,value可以是一个数值,也可以是一个函数

hasattr(object,name)

  • 判断对象是否有这个名字的属性,name必须为字符串

反射相关的魔术方法


__getattr__()__setattr__()__delattr__()这三个魔术方法,分别测试

__getattr__()

class Base:
    n = 0

class Point(Base):
    z = 6

    def __init__(self,x,y):
        self.x = x
        self.y = y

    def show(self):
        print(self.x,self.y)

    def __getattr__(self,item):
        return "missing{}".format(item)

p1 = Point(4,5)
print(p1.x)
print(p1.z)
print(p1.n)
print(p1.t)

一个类的属性会按照继承关系找,如果找不到,就会执行__getattr()方法,如果没有这个方法,就会抛出AttributeError异常表示找不到属性
查找属性顺序为:
instance.__dict__ --> instance.__class__.__dict__ --> 继承的祖先类(直到object)的__dict__ --找不到--> 调用__getattr__()

__setattr__()

  • 实例通过.点设置属性,如同self.x = x,就会调用setattr(),属性要加到实例的dict中,就需要自己完成。
class Base:
    n = 0

class Point(Base):
    z = 6

    def __init__(self,x,y):
        self.x = x
        self.y = y

    def show(self):
        print(self.x,self.y)

    def __getattr__(self,item):
        return "missing{}".format(item)

    def __setattr__(self, key, value):
        print("setattr {}={}".format(key,value))
        #self.__dict__[key] = value #正常情况下设置属性
        #return self #返回实例本身

p1 = Point(4,5)
print(p1.__dict__)
print(p1.x)
print(p1.z)
print(p1.n)
print(p1.t)
p1.name = 50
p1.x = 50
print(p1.name)
print(p1.x)
p1.__dict__["x"] = 60
print(p1.__dict__)

__delattr__()

  • 可以通过此实例删除属性的操作,但是通过类依然可以删除属性
class Base:
    n = 0

class Point(Base):
    Z = 5

    def __init__(self,x,y):
        self.x = x
        self.y = y

    def __delattr__(self,item):
        print("Can not del{}".format(item))

p = Point(4,5)
del p.x
print(p.__dict__)
p.z = 15
print(p.__dict__)
del p.z
del p.z
print(Point.__dict__)
print(p.__dict__)
print(Point.Z)
del Point.Z
print(Point.__dict__)
print(Point.Z)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值