python3中使用__slots__限定实例属性操作分析

本文实例讲述了python3中使用__slots__限定实例属性操作。分享给大家供大家参考,具体如下:

正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。先定义class:

# 类定义
class Person(object):
  pass

然后,尝试给实例绑定一个属性:

p = Person()
p.name = "jadeshu"
print(p.name)

输出:

jadeshu

还可以尝试给实例绑定一个方法:

# 类定义
class Person(object):
  pass
p = Person()
p.name = "jadeshu"
print(p.name)
def set_age(self, age): # 定义一个函数作为实例方法
  self.age = age
from types import MethodType
p.set_age = MethodType(set_age, p)
p.set_age(25)
print(p.age)

输出:

jadeshu
25

但是,给一个实例绑定的方法,对另一个实例是不起作用的:

p2 = Person() #创建新的实例
p2.set_age(25) #调用方法

出错:

Traceback (most recent call last):
25
  File "C:/Users/Administrator/Desktop/PycharmProjects/test.py", line 48, in <module>
    p2.set_age(25)
AttributeError: 'Person' object has no attribute 'set_age'

为了给所有实例都绑定方法,可以给class绑定方法:

def set_score(self, score):
  self.score = score
Person.set_score = set_score
p.set_score(80)
print(p.score)

输出:80

给class绑定方法后,所有实例均可调用:

p.set_score(80)
p2 = Person()
p2.set_score(100)
print(p.score)
print(p2.score)

输出:

80
100

通常情况下,上面的set_score方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现。

使用__slots__

但是,如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性。

为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

class Person(object):
  __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称

然后,我们试试:

>>> s = Person() # 创建新的实例
>>> s.name = 'jadeshu' # 绑定属性'name'
>>> s.age = 25 # 绑定属性'age'
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'

由于'score'没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。

使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:

>>> class Student(Person):
...   pass
...
>>> s = Student()
>>> s.score = 9999

除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python面向对象程序设计入门与进阶教程》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python编码操作技巧总结》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

(0)

相关推荐

  • Python类中的魔法方法之 __slots__原理解析

    在类中每次实例化一个对象都会生产一个字典来保存一个对象的所有的实例属性,这样非常的有用处,可以使我们任意的去设置新的属性. 每次实例化一个对象python都会分配一个固定大小内存的字典来保存属性,如果对象很多的情况下会浪费内存空间. 可通过__slots__方法告诉python不要使用字典,而且只给一个固定集合的属性分配空间 class Foo(object): __slots__ = ("x","y","z") def __init__(sel

  • Python中的__slots__示例详解

    前言 相信Python老鸟都应该看过那篇非常有吸引力的Saving 9 GB of RAM with Python's slots文章,作者使用了__slots__让内存占用从25.5GB降到了16.2GB.在当时来说,这相当于用一个非常简单的方式就降低了30%的内存使用,着实惊人.作者并没有提到他的业务特点和代码,那我们就基于<fluent python>中的例子来验证下是不是有这么厉害: from __future__ import print_function import resour

  • Python中的__SLOTS__属性使用示例

    看python社区大妈组织的内容里边有一篇讲python内存优化的,用到了__slots__.然后查了一下,总结一下.感觉非常有用 python类在进行实例化的时候,会有一个__dict__属性,里边有可用的实例属性名和值.声明__slots__后,实例就只会含有__slots__里有的属性名. # coding: utf-8 class A(object): x = 1 def __init__(self): self.y = 2 a = A() print a.__dict__ print(

  • 实例讲解Python中的私有属性

    在Python中可以通过在属性变量名前加上双下划线定义属性为私有属性,如例子: 复制代码 代码如下: #! encoding=UTF-8   class A:     def __init__(self):                  # 定义私有属性         self.__name = "wangwu"                  # 普通属性定义         self.age = 19          a = A()   # 正常输出 print a.ag

  • python中__slots__用法实例

    本文实例讲述了python中__slots__的用法.分享给大家供大家参考.具体分析如下: 定义__slots__ 后,可以再实例上分配的属性名称将被限制为指定的名称.否则将引发AttributeError,这种限制可以阻止其他人向现有的实例添加新的属性.   使用__slots__的类的实例不在使用字典来存储数据.相反,会使用基于数组的更加紧凑的数据结构. 在会创建大量对象的程序中,使用__slots__可以显著减少内存占用和使用时间 class Account(object): __slot

  • python中的__slots__使用示例

    正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: 复制代码 代码如下: >>> class Staff(object): ...     pass ... 然后,尝试给实例绑定一个属性: 复制代码 代码如下: >>> s = Staff() >>> s.name = 'jack' >>> print s.name jack >&g

  • python使用__slots__让你的代码更加节省内存

    前言 在默认情况下,Python的新类和旧类的实例都有一个字典来存储属性值.这对于那些没有实例属性的对象来说太浪费空间了,当需要创建大量实例的时候,这个问题变得尤为突出. 因此这种默认的做法可以通过在新式类中定义了一个__slots__属性从而得到了解决.__slots__声明中包含若干实例变量,并为每个实例预留恰好足够的空间来保存每个变量,因此没有为每个实例都创建一个字典,从而节省空间. 本文主要介绍了关于python使用__slots__让你的代码更加节省内存的相关内容,分享出来供大家参考学

  • 基于python3 类的属性、方法、封装、继承实例讲解

    Python 类 Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法. 对象可以包含任意数量和类型的数据. python类与c++类相似,提供了类的封装,继承.多继承,构造函数.析构函数. 在python3中,所有类最顶层父类都是object类,与java类似,如果定义类的时候没有写出父类,则object类就是其直接父类. 类定义 类定义语法格式如下: class ClassName: <statement

  • Python中__slots__属性介绍与基本使用方法

    简介 在廖雪峰的python网站上,他是这么说的 python是动态语言,它允许程序在执行过程中动态绑定属性或者方法(使用MethodTpye). 某个实例在执行过程中绑定的属性跟方法,仅在该实例中有效,其他同类实例是没有的. 可以通过给class绑定属性/方法,来给所有实例绑定属性/方法: Student.name = '' Student.set_score = set_score 而如果使用__slots__,它仅允许动态绑定()里面有的属性 例如,下面这样会报错 class Studen

  • Python编程之属性和方法实例详解

    本文实例讲述了Python编程中属性和方法使用技巧.分享给大家供大家参考.具体分析如下: 一.属性 在python中,属性分为公有属性和私有属性,公有属性可以在类的外部调用,私有属性不能在类的外部调用.公有属性可以是任意变量,私有属性是以双下划线开头的变量. 下面我们定义一个People类,它有一个公有属性name,和一个私有属性__age. class People(): def __init(self): self.name='张珊' self.__age=24 我们创建一个People类的

  • 在Python中使用__slots__方法的详细教程

    正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: >>> class Student(object): ... pass ... 然后,尝试给实例绑定一个属性: >>> s = Student() >>> s.name = 'Michael' # 动态给实例绑定一个属性 >>> print s.name Michael 还可以尝试给实例

  • 用Python中的__slots__缓存资源以节省内存开销的方法

    我们曾经提到,Oyster.com的Python web服务器怎样利用一个巨大的Python dicts(hash table),缓存大量的静态资源.我们最近在Image类中,用仅仅一行__slots__代码,让每个6G内存占用的服务进程(共4个),省出超过2G来. 这是其中一个服务器在部署代码前后的截图: 我们alloc了大约一百万个类似如下class的实例:   class Image(object):     def __init__(self, id, caption, url):   

随机推荐