python 对象树

1、python 对象树

python的继承树中的每个节点即一个命名空间,最底下的叶子为对象实例,对象实例通过 __class__ 钩子与上边的类节点连接,类通过__base__钩子与更高的超类连接。位于最顶上的根节点是type元类。

无论属性或者方法,最终都是在命名空间中爬树、进行查找,每个命名空间的存储以字典的形式进行,字典的键为属性或者方法的名称字符串

每个对象的属性的查找的命名空间顺序 MRO 是固定的,之前可能是DFS 再 BFS,目前是C3算法来实现。C3算法保证了子类永远在父类前面。

super 函数返回MRO顺序的下一个命名空间对象,主要用在多继承当中。

对于经典的菱形继承。

对于obj = D()  站在obj 对象的角度,obj 的mro顺序[D, B, C, A, object]. 

2、supper 函数

常见的 super 函数的两种用法:

1、第二个参数是一个实例:

super(B, obj) 返回下一个MRO搜索顺序的命名空间,此处的 mro 由obj.__class__ 提供。

2、第二个参数是一个类:

super(B, sometype) 返回下一个MRO搜索顺序的命名空间,此处的 mro 由 sometype 提供。

python3中 super 函数可以直接不带参数。

属性的搜索顺序:

obj.attr

obj.__getattribute__("attr")            #进行拦截。

obj.__dict__["attr"] 及父类的.__dict__["attr"]             #如果在树中找到

obj.__getattr__("attr")      #如果在树中没有定义,即没找到

 

class D(object):
    def __init__(self):
        self.test=20
        self.test2=21
    def __getattribute__(self,name):
        if name=='test':
            return 0.
        else:
            return object.__getattribute__(self, name)
            #super(D, self).__getattribute__(name)
            #super().__getattribute__(name)   #python3中可以这样写

 

注意这里超类使用 __getattribute__  通过 self 来正常的获取属性,即使属性不在超类中,解释器开洞!!!这样抛到高层的超类中,也是为了避免无限循环。

3、静态方法、实例方法、类方法

class Normal:  #通过实例对象来调用时有绑定
	def func(x):
		print("normal")
n = Normal()
n.func()        #实例对象来调用,实例对象自动绑定到方法的一个参数
Normal.func(9)  #通过类调用,第一个参数可以任意传入

class CM:  #通过实例对象和类来调用都需要绑定
        @classmethod
	def func(x):
		print("classMethod")
cm = CM()
cm.func()
CM.func()   #实例对象和类自动绑定到第一个参数

class StaticC:  #不绑定
	@staticmethod
	def func(x):
		print("staticMethod")
sobj = StaticC()
sobj.func(3)
StaticC.func(3)  #不绑定到参数

 

python的所有方法都可以通过类实例对象和类来调用。对于普通方法而言,通过实例对象来调用,实例对象自动被绑定到第一个参数(约定名称为self),但是通过类来调用,不绑定该参数,所以该参数可以任意传入,没有任何约束。对于类方法,通过实例对象和类来调用,都自动绑定到第一个参数,所以类方法至少需要一个参数。对于静态方法,通过类和实例来调用,不做任何参数绑定,所以所有的参数都需要额外传入。

4、dir() 函数属性获取

__dict__ 只包含每个节点命名空间自身的属性,dir() 则会爬树,从实例爬到类,再爬完所有的父类,但是不包括类所属的类(即元类)。普通类都可以调用 .mro() 方法,但是该方法其实是终极元类 type 所有,包括 __base__,__class__ 都是从 type 元类所来,所以 dir() 列表中没有。

5、type 与 object 的关系

python 中一切都是对象,但是对象有其所属的类。所以存在两种关系:

1、对象与类之间的某个对象是否属于某个类的 isinstance 的关系。

2、类与类之间是否存在继承的 issubclass 的关系。

object 是所有类的父类,所以 issubclass(anyclass, object) 都是 True。type 则是所有类的类,所有 isinstance(anyclass, type)都是 True.

 唯一的一个 False 是 issubclass(object, type).

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值