8.python之面相对象part.8(__slots__属性)

一.__slots__属性有什么作用?为什么要有__slots__属性。

首先来说一说__slots__是什么,__slots__是一个类变量,它里面的值可以是字符串,可以是列表,可以是元组。(如果__slots__这个属性的值为一个字符串,那么意为着这个类生成的对象,只能有一个属性)。

那么为什么要用__slots__属性呢?

关于这个问题还要从每个对象的__dict__属性开始说起。

当使用.点来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,而每个实例的是独立的),如果一个类,生成了很多的对象,每生成一个对象时,都会为这个对象生成一个__dict__属性字典,如果有很多类就会生成很多的字典,会占用很多的内存空间。

如果你有一个属性很少的类,但是有很多实例,为了节省内存可以使用__slots__取代实例的__dict__啦~

当你定义__slots__后,__slots__就会为实例使用一种更加紧凑的内部表示。实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个字典。

这跟元组或列表很类似。在__slots__中列出的属性名在内部被映射到这个数组的指定小标上。

!!使用__slots__的一个缺点就是我们不能再给实例添加新的属性了,只能使用在__slots__中定义的那些属性名。这点是非常值得注意的!!

二.关于使用__slots__属性的主意事项。

  1. 使用__slots__属性后,无法在给对象添加新的属性!只能使用在类中__slots__属性中定义的属性名!!!
  2. 定义了__slots__属性后的类,将不再具备普通类的一些特性,比如:多继承。大多数情况下,你应该明确,某些在程序中会创建几百万个对象的类,就需要使用__slots__属性,并且只在那些经常被使用到 的用作数据结构的类上定义__slots__。

三.关于__slots__的一些补充。

关于__slots__的一个常见误区是它可以作为一个封装工具来防止用户给实例增加新的属性。尽管使用__slots__可以达到这样的目的,但是这个并不是它的初衷。 更多的是用来作为一个内存优化工具。

四.关于__slots__的使用方法演示。

例1:

class Foo:

__slots__=‘x‘

f1=Foo()

f1.x=1

f1.y=2#报错

print(f1.__slots__) #f1不再有__dict__

class Bar:

__slots__=[‘x‘,‘y‘]

n=Bar()

n.x,n.y=1,2

n.z=3#报错

例2:(__slots__特性的验证)

class Foo:

__slots__=[‘name‘,‘age‘]

f1=Foo()

f1.name=‘alex‘

f1.age=18

print(f1.__slots__)

f2=Foo()

f2.name=‘egon‘

f2.age=19

print(f2.__slots__)

print(Foo.__dict__)

#f1与f2都没有属性字典__dict__了,统一归__slots__管,节省内存

时间: 2024-11-05 23:25:53

8.python之面相对象part.8(__slots__属性)的相关文章

8.python之面相对象part.6(反射&__call__,__setattr__,__delattr__,__getattr__)

一.什么是反射? 反射,又被称为自省,主要是指程序本身可以访问,检测,和修改"自己",状态或行为的一种能力. 二.python是如何体现这种反射机制的? 通过字符串去操作对象相关的属性,python中,一切皆对象,所有的地方都可以用到反射. python内部提供了四个实现反射(自省)的函数,这四个函数可以适用于任何的类和对象(这是因为类本身也是一个对象!) 1.hasattr(object,str) 用来检测一个对象中是否有某个字符串对应的方法或者属性. 例如: l1 = [] pri

python之面相对象进阶

一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(object): 2 pass 3 4 obj = Foo() 5 6 isinstance(obj, Foo) issubclass(sub, super)检查sub类是否是 super 类的派生类 1 class Foo(object): 2 pass 3 4 class Bar(Foo): 5 pass

8.python之面相对象part.2(特殊属性,类方法,静态方法)

一.关于特殊属性(property). 接着上一篇文章继续说,如果想调用python中一个对象的属性,直接使用类或者对象名称在后面加.点然后写上属性名称就可以跳用这个类或者对象的属性了,比如说像下面这样. class person: def __init__(self,career): self.career = career ayumi = person(career="diva") print ayumi.career #ayumi是实例化出来的一个对象后面加.点,后面接属性名,就

python之面相对象程序设计

一 面向对象的程序设计的由来 面向对象设计的由来见概述:http://www.cnblogs.com/linhaifeng/articles/6428835.html 面向对象的程序设计:路飞学院版 二 什么是面向对象的程序设计及为什么要有它 面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式. 优点是:复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将

8.python之面相对象part.1(初识类与对象)

一.类和对象的概念. 什么是类 类就是把一类事物相同的特征和动作整合到一起就是类比如说"人"就是一个类. 什么是对象 对象就是基于类创建出来的一个具体存在的事物这个事物包含了将其创造出来的类的特征和动作. 类与对象有什么关系一切的对象都是由类产生的假如说造一支笔首先要有一个造笔的模版上帝制造人也是一样制造一个人也需要一个造人的模版这个模板就是人的"类"然后根据类的定义来产生一支支笔和一个个的人. 什么是实例化 由类产生对象的过程就是实例化类实例化的结果就是一个对象对

8.python之面相对象part.5(子类调用父类的方法,以及super关键字)

python中子类要调用父类的某个方法,在python早期版本中是这样实现的: class A: def __init__(self): print "enter A" print "leave A" class B(A): def __init__(self): print "enter B" A.__init__(self) print "leave B" b = B() >>>enter B enter

补8.python之面相对象part.6(补充授权与继承的概念)

一.什么是python中对类的"包装". (简单来说,包装就是通过类继承的特性为类增加或者修改类中原有的功能) 举个例子,python内部提供了很多标准的数据类型,以及很多的内置方法,在有一些场景下,我们需要基于标准数据类型去定制自己所需要的数据类型,新增或者改写一些类的方法,在做这种操作的时候,就需要用到类继承相关的知识.(python自带的标准类也可以通过"包装"这种方式来进行二次加工.) 例子1:给python的list列表类增加一个功能,这个功能可以查看列表

8.python之面相对象part.4(接口继承的思想设计,这种东西也叫抽象类)

接口继承也叫做程序的归一化设计,这种东西也有人叫它抽象类. 那么什么又是抽象类呢? 抽象类这种东西,只能被继承,不可以被实例化. 如果说一个类是从一堆对象中抽取出来的,那么一个抽象类,就是从一堆类中抽取出来的. 简单的说,抽象类与普通类最大的不同之处就是,抽象类中的方法都试抽象的,没有办法实现具体的功能,这种抽象类不能生成对象,只可以被继承,但是,继承了这个抽象类的子类,必须去实现抽象类所抽象出来的方法!这个概念很像接口,所以说,我把它理解为接口式的继承. 关于抽象类的定义概念,可以参考下面这个

8.python之面相对象part.6(python类中的多态与多态性)

一.什么是多态性? 多态性依赖于类的继承特性和派生特性,多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数. 为了更好的理解,接下来拿len()函数来举个例子: len()函数的功能是用来求一个序列的长度,那么len()这个函数是如何获取到序列的长度的呢? len()函数就是通过执行对象的__len__方法来获取到一个序列的长度. python中常见的一些基本数据类型, 比如字符串,字典,列表,元组 都具有名为__len__方法,所以len()函数无序知道