第六章 与对象的深入交往 总结

一 一切皆对象

1 运算符


1.1.1运算符中的特殊方法的操作

如果用dir(list)调查list的属性,可以看到一个属性是_add_()这个特方法,它定义了“+”运算符对于list对象的意义。两个list的对象相加时,会进行合并列表的操作。

>>>print([1,2,3]+[5,6,9]) #得到 [1,2,3,5,6,9]

运算符,比如+、-、>、<、and、or的能都是通过特殊方法实现的。

>>>" abc "+ "xyz" #连接字符串,获得“abcxyz”,实际上执行了”abc._add_("xyz")的操作

两个对象能否进行加法运算的关键就要看相应的对象是否有_add_()方法。

别的例子:

>>>(1.8)._mul_(2.0) #1.8*2.0

>>>True._or_(False) #True or False


1.2.1 运算符中特殊方法的拓展操作

运算相关的特殊方法还可以改变执行运算的方法。

比如>>>[1,2,3]-[3,4] 是无法进行减法操作的,因为列表没有定义“-”的运算符,我们可以创建一个列表的子类,通过增加_sub_()的方法来增加减法操作的定义。


2 元素引用

2.1 _gtitem_()方法

下面时我们常见的表元素引用方法:

li=[1,2,3,4,5,6]

print(li[3]) #打印4

上述python发现并理解[]符号,然后调用_getitem_()方法

li=[1,2,3,4,5,6]

print(li._getitem_(3)) #打印4



3 内置函数的实现

与运算符类似,许多内置函数也都是调用对象的特殊方法。

>>>len([1,2,3]) #返回表中元素的综合

实际上是:

>>>[1,2,3]._len_()

别的例子:

>>>(-1).__abs__()

>>>(2.3).__int__()

二 属性管理

1 属性管理

1.1属性管理的背后

为了深入理解属性覆盖,我们有必要理解Python的__dict__属性。当我们调用调用对象的属性时,这个属性可能来自对象属性、类属性、还有可能从祖先类那里继承来的。一个类或对象拥有的属性,会记录再__dict__中。这个__dict__时一个词典,键为属性名,对应的值为某个属性。python在寻找对象的属性时,会按照继承关系依次寻找__dict__

一个例子:

子类的属性不父类的同名属性有优先权,这正是属性覆盖的关键。

值得注意的是:上面都是调用属性的操作,如果进行赋值,那么Python就不会分层深入查找了。


2 特性

同一个对象的不同属性之间可能存在依赖关系。 当某个属性被修改时,我们希望以来与该属性的其他属性也同时变化。python提供了多种即时生成属性的方法,其中一种称为特性(property)。即特殊的属性。

特殊属性通过内置函数property()来建立。property()最多可以加载四个参数,前三个参数为函数,分别用于设置获取、修改和删除特性时,Python应该执行的操作。最后一个参数为特性的文档,可以为一个字符串起到说明作用。

一个例子:



3 .__getattr__()方法

除了内置函数property外,我们还可以用__getattr__(slef,name)来查询即时生成的属性。


每个特性都需要有自己的处理函数,而__getattr__()可以将所有的及时生成属性都放在同一个函数集中处理。需要特别注意的是,__getattr__()只能用于查询不在__dict__系统中的属性。

三 我是风儿,我是沙

1 动态类型(Dynamic Typing)

几个概念:

对象名是只想这一对象的引用(reference),对象是村粗在内存中的实体

①通过内置函数id(),我们能看到引用指向的是哪个对象:


返回的编号相同

②除了直接打印的id外,我们还可以用is运算来判断两个引用是否指向同个对象。

2 变与不可变对象

①一个对象可以有多个引用,看下面这个例子:#不可变对象的例子

对象没变,只是引用变了,从效果上看就是各个引用各自独立,互不影响。这就是不可变对象

②列表自身能发生改变的对象,称为可变对象(Mutable Object)

一个例子:


3 从动态类型看函数的参数传递

函数的参数传递本质上传递的是引用。

不可变对象


可变对象


四 内存管理


1 引用管理

对象内存管理是基于对引用的管理。在Python中,引用与对象分离。一个对象可以有多个引用,而每个对象都存有指向该对象的引用总数,即引用计数(Reference Count)

我们可以i使用标准库中sys包中的getrefcount(),来查看某个对象的引用计数,需要注意的是,当使用某个引用作为参数,传递给getrefcount()时,参数实际上时创建了一个临时引用。因此,getrefcount()所得到的结果会比期望多1.



2 对象引用对象


对象引用对象的例子

注意:当一个对象a被另一个对象b引用,a的引用计数将增加1:


容器对象的引用可能会构成很复杂的拓扑结构:

x=[1,2,3]

y=[x,dict(key1=x)]

z=[y,(x,y)]

import objgraph

两个对象可能相互引用,从而构成引用环(Reference Cycle)

a=[ ]

b=[a]

a.append(b)

即便是单个对象,只需要自己引用自己,也能构成引用环:

a=[ ]

a.append(a)

print(getrefcount(a))

3 垃圾回收(Garbage Collection)

3.1基础回收

原理上,当Python的某个对象的引用计数降为0了,即没有任何引用指向对象时,该对象就成为要被回收的垃圾了。

如:

a=[1,2,3]

del a #删除a之后,没有任何引用指向[1,2,3],表[1,2,3]将被清除

Python指挥在特定的条件下,自动启动垃圾回收。当Python运行时,会记录其中分配对象那个和取消分配对象的起初,当两者的差值高于某个阈值时,垃圾回收才会启动。

我们可以通过gc模块的get_threshold()方法,查看该阈值。

import gc

print(gc.get_threshold())

返回(700,10,10)后面的两个10时与分代回收相关的阈值。700是立即回收启动的阈值。


3.2分代回收

python同时还采用了分代回收的策略。

python将所有对象分为0、1、2三代。所有新建对象都是0代对象。当某一带对象经历过垃圾回收,依然存活,那么它将被归入下一代对象。垃圾回收启动时,一定会扫描所有0代对象。如果0代对象经历过一定次数的垃圾回收,那么就启动对0代和1代的扫描清理。当1代也经历了一定次数的垃圾回收后,就启动对0、1、2代的扫描,即对所有对象进行扫描。

get_threshold()返回的(700,10,10)返回的两个10,意思是,每10次0代垃圾回收,会配合1次1的乐基回收,而每10次1代回收,才会有1次2代的垃圾回收。

可以采用set_threshold()来调整次数

import gc

gc.set_threshold(700,10,5)

4 孤立的引用环

这些引用环可能构成无法使用,但引用计数不为0的一些对象,会给垃圾回收机制带来很大的困难。

为了回收这样的引用环,Python会赋值每个对象的引用计数,可以记作gc_ref。假设,每个对象i,该计数为gc_ref_i.Python会遍历所有的对象i。对于每个对象i所引用的对象j,将相应的gc_ref_j减1.

在结束遍历后,gc_ref不为0的对象和这邪恶对象引用的对象,以及继续更下游引用的对象,需要被保留,而其他对象则被垃圾回收。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,050评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,538评论 1 306
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,673评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,622评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,047评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,974评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,129评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,893评论 0 209
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,654评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,828评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,297评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,619评论 3 262
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,326评论 3 243
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,176评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,975评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,118评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,909评论 2 278

推荐阅读更多精彩内容