动态添加属性的问题

通过前面的学习中我们知道, 由于 pytyon 的动态语言的特性, 我们可以动态的给对象添加属性和方法.

但是这种方式添加的属性和方法, 只在当前对象上有用, 在其他对象上是没用.


class A:
    pass

a1 = A()
a1.name = "李四"  #给 a1 对象添加一个属性
print(a1.name)

a2 = A()
print(a2.name)    # a2中没有 name 属性, 所以抛异常


__slot__的基本使用

添加属性和方法最好直接在类中添加, 这样所有的对象都可以拥有了.

如果我想避免把某些属性直接添加到实例对象上, 可以使用一个特殊属性:__slot__类实现.

__slot__定义一个元组, 则元组内的属性名允许在实例对象上直接添加, 其他的都不允许.

class A:
    __slots__ = ("name", )


a1 = A()
a1.name = "李四"  # 给 a1 对象添加一个属性   name 属性是允许的
print(a1.name)
a1.age = 20    # age 不允许, 所以抛异常
print(a1.age)

注意:

  1. 我们的__init__()中添加属性是在self上添加的, 其实也是直接在对象上添加, 所以没有在元组中的属性名, 也是不允许的.

  2. 对于我们直接在类中添加方法是没有任何的影响的.

class A:
    __slots__ = ("name",)

    def __init__(self):
        self.age = 30  # 也是不允许的


a = A()


继承中的__slot__

__slot__只对当前类有用, 对他的子类不起作用. 所以子类也要有自己的__slot__

class A:
    __slots__ = ("name",)

    def __init__(self):
        self.age = 30  # 也是不允许的


class B(A):
    def __init__(self):
        self.age = 30 # 子类是允许的


b = B()
print(b.age)


__slot__对性能上的提升

一些人把__slot__作为一种安全的特性来实现, 然后实际上他对内存和执行速度上的性能优化才是最重要的.

不使用__slot__, python 使用字典的方式去存储实例数据的, 如果一个程序使用大量的实例, 则内存占用和执行效率都会影响比较大.

使用__slot__后, python 存储实例数据的时候, 不再使用字典, 而是使用一种更加高效的基于数组的数据结构. 可以显著减少内存占用和执行时间.

Copyright © 李振超 2018 all right reserved,powered by Gitbook
该文件最后修订时间: 2018-02-25 07:12:09

results matching ""

    No results matching ""