__slots__,__doc__,__module__,__class__.__call__

__slots__

1.__slots__是什么:是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)
2.引子:使用点来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,而每个实例的是独立的)
3.为何使用__slots__:字典会占用大量内存,如果你有一个属性很少的类,但是有很多实例,为了节省内存可以使用__slots__取代实例的__dict__
当你定义__slots__后,__slots__就会为实例使用一种更加紧凑的内部表示。实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个
字典,这跟元组或列表很类似。在__slots__中列出的属性名在内部被映射到这个数组的指定小标上。使用__slots__一个不好的地方就是我们不能再给
实例添加新的属性了,只能使用在__slots__中定义的那些属性名。
4.注意事项:__slots__的很多特性都依赖于普通的基于字典的实现。另外,定义了__slots__后的类不再 支持一些普通类特性了,比如多继承。大多数情况下,你应该
只在那些经常被使用到 的用作数据结构的类上定义__slots__比如在程序中需要创建某个类的几百万个实例对象 。
关于__slots__的一个常见误区是它可以作为一个封装工具来防止用户给实例增加新的属性。尽管使用__slots__可以达到这样的目的,但是这个并不是它的初衷。
更多的是用来作为一个内存优化工具。
class Foo:
    __slots__ = 'x'     #所有slots后的类,都没有__dict__属性
    #__slots__ = ['name','age']  #可以放字符串,列表等等的类型
f1 = Foo()
#f1.x = 1
#f1.y = 2    #只能放一个位置X,所以加第二个报错AttributeError: 'Foo' object has no attribute 'y'
print(f1.name,f1.age)
print(f1.__dict__)  #没有__dict__属性 AttributeError: 'Foo' object has no attribute '__dict__'
print(f1.__slots__)
#没有属性字典__dict__了,统一归__slots__管,节省内存


__doc__

取文件描述信息

class Foo:
    '我是描述信息'
    pass
print(Foo.__doc__)  #可以取到描述信息
#执行结果:我是描述信息

 


__module__、__class__


__module__输出模块信息

__class__输出模块信息加类名

class C:
    def __init__(self):
        self.name = 'sb'
obj = C()
print (obj.__module__)  # 输出 __main__,即:输出模块
#执行结果:如果是当前文件,返回__main__,如果是其它,返回调用的__name__
print (obj.__class__)   # 输出 <class '__main__.C'>,即:输出类
#执行结果:<class '__main__.C'>          模块.类名

__call__

对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:
    #pass
    def __call__(self, *args, **kwargs):
        print('执行__call__')
f1 = Foo()
f1()    #原本会报错TypeError: 'Foo' object is not callable
        #但是加上__call__方法后,f1对象加上括号是可以执行的

 

posted @ 2016-12-29 15:00  总要做些什么  阅读(211)  评论(0编辑  收藏  举报