object
类是全部类的父类,所以全部的类都有object类的属性和方法。咱们显然有必要深刻研究一下object类的结构。对于咱们深刻学习Python颇有好处。
其实咱们在前面第17讲介绍继承的时候,其实就已经介绍object
根类的一部分,包括使用mro()
函数查看类的继承关系,此次咱们从另外角度来讲明object
根类。python
仍是经过一个例子开始:git
class Person: count = 0 def __init__(self, name, age): self.name = name self.age = age def say_age(self): print("{0}的年龄是:{1}".format(self.name, self.age)) obj = object() print(dir(obj)) s = Person("聂发俊", 100) print(dir(s))
运行结果:github
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'count', 'name', 'say_age']
程序说明:
这段程序已经很熟悉了,运行原理就不过多赘述了。咱们对比一下对象obj
和对象s
所返回的属性列表,发现相比增长了一下几个属性:__dir__
, __module__
,__weakref__
,age
,count
,name
,say_age
。首先说简单的:markdown
name
,age
count
say_age
__dir__
属性列表只有存在类方法(静态方法)、类属性、实例属性、实例方法中至少一项,才会有__dict__
属性。如上面例子中的对象obj
,就没有__dict__
属性。ssh
__module__
模块属性表明当前对象运行的模块ide
class Person: pass p = Person() print(p.__module__)
运行结果:函数
__main__
程序说明:默认运行在__main__
模块下。学习
__weakref__
弱引用属性提及弱引用,就不得不说前面提到的Python垃圾回收机制,垃圾回收机制最核心的机制就是引用计数。weakref
的弱引用是相对于引用计数而言的,引用计数的方式也能够叫作常规引用或者强引用(后面我的定义,若是不对,请多多指教。)
相同点: 不管是常规引用仍是弱引用,都可以经过引用的方式获取到被引用对象的地址,换句话说,就是能够具备被引用对象的想用的操做
区别:常规引用会增长引用计数,可是弱引用不会增长引用对象this
默认状况下是没有弱引用的:code
class Person: pass p = Person() print(p.__weakref__)
运行结果:
None
程序说明:普通对象在默认状况下是不存在弱引用的。
下面咱们就介绍一下弱引用常见的两种形式
weakref.ref(p_object)
方法使用weakref.ref
方法是最常规的方法,返回的是一个weakref
类型对象,若是须要只用引用,须要经过()
才能获取到被引用对象。
示例代码:
import weakref import sys class Person: def __init__(self, name, age): self.name = name self.age = age def ref_callback(reference): print("ref_callback") print(reference, "this weak reference invalid") p1 = Person("聂发俊", 100) print(sys.getrefcount(p1)) # 使用weakref.ref方法构建弱引用 wek1 = weakref.ref(p1, ref_callback) print(sys.getrefcount(p1)) print("--" * 20) print(p1.__weakref__) print(wek1) print(wek1()) print("{0}的年龄是:{1}".format(wek1().name, wek1().age)) print('--' * 20) del p1 print(wek1)
运行结果:
2 2 ---------------------------------------- <weakref at 0x00000260D5978CC8; to 'Person' at 0x00000260BE779908> <weakref at 0x00000260D5978CC8; to 'Person' at 0x00000260BE779908> <__main__.Person object at 0x00000260BE779908> 聂发俊的年龄是:100 ---------------------------------------- ref_callback <weakref at 0x00000260D5978CC8; dead> this weak reference invalid <weakref at 0x00000260D5978CC8; dead>
程序说明:
__weakref__
也有值了,指向和wek1
同样的地址。wek1
是一个weakref
类型的对象,只有使用wek1()
的方式,才能获取被引用对象__main__.Person
,使用被引用对象的实例属性,也须要带上()
ref_callback
,同时wek1
的弱引用状态变成dead
状态。weakref.proxy(p_object, callback)
方法使用weakref.proxy
方法建立弱引用返回被引用对象,相似于a=b
操做,这个是和使用ref
函数不同的地方。
示例代码:
import weakref import sys class Person: def __init__(self, name, age): self.name = name self.age = age def proxy_callback(reference): print("proxy_callback call") p1 = Person("聂发俊", 100) print(sys.getrefcount(p1)) # 使用weakref.proxy方法构建弱引用 wek2 = weakref.proxy(p1, proxy_callback) print(sys.getrefcount(p1)) print("--" * 20) print(p1) print(wek2) print("{0}的年龄是:{1}".format(wek2.name, wek2.age)) print('--' * 20) del p1 print(wek2)
运行结果:
2 2 ---------------------------------------- <__main__.Person object at 0x0000010E9784F388> <__main__.Person object at 0x0000010E9784F388> 聂发俊的年龄是:100 ---------------------------------------- proxy_callback call Traceback (most recent call last): File "test.py", line 30, in <module> print(wek2) ReferenceError: weakly-referenced object no longer exists
程序说明:
weakref.proxy
返回的被引用对象,p1
和wek2
指向相同的地址0x000001EFF7219908
,使用实例属性不须要()
p1
,方法weakref.proxy
指定的回调函数proxy_callback
会被调用,注意由于被引用对象先被删除,而后在执行回调函数,这个时候虽然有参数reference代指被引用对象,可是不能使用,由于已经被删除了 wek2
会提示错误信息,由于被引用对象p1
被删除了,没法获取对象weakref.ref()
返回weakref
,使用被引用对象须要使用()
进行辅助,删除被引用对象时,weakref
状态变成dead
.weakref.proxy()
返回被引用对象,能够直接使用被引用对象,删除被引用对象时,proxy
不能再继续使用,没法再获取被引用对象。备注:
更多精彩博客,请访问: 聂发俊的技术博客
对应视频教程,请访问: python400
完整markdown笔记,请访问: python400_learn_github