__slot__使用说明

廖雪峰的python网站上,他是这么说的

python是动态语言,它允许程序在执行过程中动态绑定属性或者方法(使用MethodTpye)。

某个实例在执行过程中绑定的属性跟方法,仅在该实例中有效,其他同类实例是没有的。
可以通过给class绑定属性/方法,来给所有实例绑定属性/方法:

Student.name = ''
Student.set_score = set_score

而如果使用__slots__,它仅允许动态绑定()里面有的属性
例如,下面这样会报错

class Student():
  __slots__ = ('name', 'age')

S1 = Student()
S1.name = 'Jack'  # ok!
S1.score = 123  # error!

但是我觉得很奇怪,仅有这一个作用吗?于是我再查了其他资料,发现这个函数可以很可观地节约内存,大概能节约40%~50%(详见这里

在python中,它是使用字典来保存一个对象的实例属性的。这非常有用,因为它允许我们我们在运行时去设置任意的新属性。

但是,这对某型已知属性的类来说,它可能是一个瓶颈。因为这个字典浪费了很多内存。

python不能在对象创建的时候直接分配一个固定量的内存来保存所有属性,因此如果你有成千上万的属性的时候,它就会消耗很多内存。

有一个办法可以规避这个问题,就是使用__slots__来告诉python不要使用字典,而是只给一个固定集合的属性分配空间。

可以通过下面的例子来感受下:

Python 3.4.3 (default, Jun  6 2015, 13:32:34)
Type "copyright", "credits" or "license" for more information.

IPython 4.0.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import ipython_memory_usage.ipython_memory_usage as imu

In [2]: imu.start_watching_memory()
In [2] used 0.0000 MiB RAM in 5.31s, peaked 0.00 MiB above current, total RAM usage 15.57 MiB

In [3]: %cat slots.py
class MyClass(object):
        __slots__ = ['name', 'identifier']
        def __init__(self, name, identifier):
                self.name = name
                self.identifier = identifier

num = 1024*256
x = [MyClass(1,1) for i in range(num)]
In [3] used 0.2305 MiB RAM in 0.12s, peaked 0.00 MiB above current, total RAM usage 15.80 MiB

In [4]: from slots import *
In [4] used 9.3008 MiB RAM in 0.72s, peaked 0.00 MiB above current, total RAM usage 25.10 MiB

In [5]: %cat noslots.py
class MyClass(object):
        def __init__(self, name, identifier):
                self.name = name
                self.identifier = identifier

num = 1024*256
x = [MyClass(1,1) for i in range(num)]
In [5] used 0.1758 MiB RAM in 0.12s, peaked 0.00 MiB above current, total RAM usage 25.28 MiB

In [6]: from noslots import *
In [6] used 22.6680 MiB RAM in 0.80s, peaked 0.00 MiB above current, total RAM usage 47.95 MiB

参考:

https://eastlakeside.gitbooks.io/interpy-zh/content/slots_magic/
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143186739713011a09b63dcbd42cc87f907a778b3ac73000

### PCI Slot 扫描的技术信息 在 Linux 系统中,PCI 总线扫描是一个复杂的过程,涉及多个阶段和函数调用。以下是关于 `pci_scan_slot` 和相关技术的具体说明: #### 1. **PCI 插槽扫描的核心函数** Linux 内核提供了专门用于扫描 PCI 插槽的函数 `pci_scan_slot`[^4]。此函数的主要功能是对指定的 PCI 总线上的某个插槽进行遍历,并检测是否存在有效的 PCI 设备。 ```c struct pci_dev *pci_scan_slot(struct pci_bus *bus, int devfn); ``` - 参数解释: - `bus`: 表示要扫描的 PCI 总线对象。 - `devfn`: 是一个组合值,表示设备号 (`dev`) 和功能号 (`func`) 的位移编码。 通过调用该函数,可以逐一检查每个可能的设备位置,直到找到有效设备为止。 --- #### 2. **扫描过程中的关键步骤** ##### (1) **读取 Vendor ID 和 Device ID** 为了确认某插槽上是否有实际存在的硬件设备,内核会尝试读取其 Vendor ID 和 Device ID 值。如果返回的是无效值(如全零),则认为该插槽为空[^5]。 ```c u32 pci_bus_read_dev_vendor_id(struct pci_bus *bus, unsigned int devfn, u32 *vendor_id, struct pci_sysdata *sd); ``` 上述代码片段展示了如何利用底层接口访问特定寄存器来获取这些基本信息。 ##### (2) **注册发现的新设备** 一旦识别到新的 PCI 设备,它会被加入全局链表并分配唯一的资源描述符。这一步骤通常由辅助函数完成,例如 `pci_scan_single_device` 和 `pci_create_device`。 --- #### 3. **配置选项的影响** 某些情况下,是否启用 BIOS 提供的支持或者直接操作硬件会影响最终的行为模式。具体来说,以下几个编译期参数起到决定作用[^3]: - `CONFIG_PCI_BIOS=n`: 关闭对传统 BIOS 方法的支持; - `CONFIG_PCI_MMCONFIG=y`: 启用 MMCFG 方式的内存映射访问机制; - `CONFIG_PCI_DIRECT=y`: 使用直接 I/O 访问路径而非间接方式; 调整它们可能会改变性能表现以及兼容性范围,请谨慎修改默认设置! --- #### 4. **动态重扫支持** 除了初始化期间执行的一次全面探测外,在运行时也可以触发额外轮次的手动刷新动作。借助 sysfs 文件系统暴露出来的控制节点即可实现这一目标: ```bash echo 1 > /sys/bus/pci/rescan ``` 这条命令告诉核心层再次审视当前连接状况,并相应更新内部数据结构树形图视图。 --- ### 示例代码展示完整的流程逻辑 下面给出了一段伪代码样例,概括了从顶层到底层逐级深入探索整个体系架构的大致思路框架: ```c void pci_scan_all_buses(void){ foreach(bus in root_bridges){ pci_register_host_bridge(bus); // 注册主机桥接控制器实例 while(pci_next_child_bus(bus)){ pci_scan_child_bus(current_child); // 遍历子集 foreach(slot within current_child){ if(is_valid_device_at_slot(slot)){ register_new_pci_device(); // 创建新条目记录详情 } } } } } ``` 注意这里仅作为概念示意用途,并未完全遵循真实源码布局风格。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值