python类与对象part2

本文介绍使用__slots__减少Python类实例占用的内存及如何通过单下划线和双下划线对类的属性和方法进行封装,避免外部直接访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.当创建大量实例时如何节省内存

对于那些主要用作简单数据结构的类,通常可以在类定义中增减__slot__属性,以此来减少对内存的使用

class Date():
    __slots__ = ['year', 'month', 'day']
    def __init__(self,year,month,day):
        self.year = year
        self.month = month
        self.day = day

当定义了__slots__属性的时候,python就会针对实例采用一种更加紧凑的内部表示,不再让每一个实例都创建一个__dict__字典,现在的实例是围绕着一个固定长度的小型数组来创建的,这和一个元组或者列表很相似。

注意:

  • 使用__slots__之后我们将没办法再对实例添加任何新的属性——我们被限制只允许使用__slots__中列出的那些个属性名。
  • 定义了__slots__的类不支持某些特定的功能,比如多继承。

就大部分而言,我们应该只针对那些在程序中被当做数据结构而频繁使用的类采用__slots__技法,所以一般不建议使用。

如下例:

class Date():
    __slots__ = ['year', 'month', 'day']
    def __init__(self,year,month,day):
        self.year = year
        self.month = month
        self.day = day

d = Date('2017','09','08')
d.__setattr__('ha','hi')
print(d.ha)
Traceback (most recent call last):
  File "D:/github/pycharmDevelopment/numpyy.py", line 35, in <module>
    d.__setattr__('ha','hi')
AttributeError: 'Date' object has no attribute 'ha'

但是当我们将__slots__ = [‘year’, ‘month’, ‘day’]这一行注释掉之后就不会有错误,输出结果为hi,由此可见__slots__阻止了示例的属性添加

2. 将名称封装到类中

在python中我们习惯使用特定的命名规则来表达对数据和方法的用途。
第一个规则是任何以单下划线(_)开头的名字应该总是被认为只属于内部实现。

Python不会阻止其他人访问内部名称,但是如果有人这么做了,那么被认为是粗鲁的,并且会导致代码的脆弱不堪。

class Animal():
    def __init__(self,kind):
        self.kind = kind
        self.__private = 0
        self._inter = 1
    def __private_method(self):
        print('Animal')

class Bird(Animal):
    def __init__(self,kind):
        super().__init__(kind)
        self.__private = 2
        self._inter = 3

    def __private_method(self):
        print('Bird')

bird=Bird('bird')
print(bird._inter)#结果是3

以双下划线打头的名称会导致出现名称的重整行为,以上面的例子来说,私有属性会分别被重命名为_B__private和_B__private_method。对于名称重整我们必须要知道的是:私有属性和方法是不能通过继承而被覆盖的。

bird=Bird('bird')
print(bird._Animal__private)
bird._Animal__private_method()
print(bird._Bird__private)
bird._Bird__private_method()
输出结果为:
0
Animal
1
bird
可见私有属性和方法都没有被覆盖掉

对于单或者双下划綫名称,我们应该尽量让非公有名称以单下划线开头,对于代码中会涉及子类话处理而且有些内部属性应该对子类进行隐藏,那么此时就应该使用双下划线了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值