最近,我发现了一个名为swifter的有用库,它可以加快python中panda系列的处理速度。我确信它在后台进行了大量的矢量化处理和优化,但我很好奇它是如何通过导入来为pandas系列或数据帧对象引入新属性的。以这个最小的代码为例。
#!/usr/bin/env python3
# encoding: utf-8
import pandas as pd # Version 1.4.1
import numpy as np # Version 1.22.3
samples:int=2**20
colname:str='Value'
frame=pd.DataFrame(data={colname:np.random.randint(low=0, high=45353, size=samples)})
import swifter # Version 1.22.3 The following line throws an attribute error without this import
frame[colname].swifter # With swifter imported, this is swifter.SeriesAccessor object
这看起来真的很神奇,因为我认为import语句可以引入新的类、函数等,但不能改变命名空间中已经存在的对象的API(可用方法(。这在某种程度上与我的OOP范式中对象如何工作和交互的心理模型相冲突。任何关于如何做到这一点的指导,或者它是否使用了python语言的一些更深层次的高级功能,都将是非常棒的。
导入模块或包时,Python会加载并执行其中的代码。
当您import swifter
时,Python加载swifter.__init__
文件,该文件包含:
if "modin.pandas" in sys.modules:
register_modin()
当条件为真时,执行register_modin
。通常,当您导入模块或包时,代码除了在本地作用域中注册一些变量、函数或类之外,没有任何副作用。
为了避免魔术,好的做法是:
from swifter import register_modin
register_modin()
查看pandas.api.extensions.register_dataframe_accessor