首页 > 解决方案 > 将 .py 文件转换为 .pyd 文件时的 UndefinedVariableError 包括 df.query("foo=@bar") 之类的行

问题描述

我从未使用过 Cython,但我需要加密我的源代码。

我的问题是,如何将包含像 Cython 这样的行的 python 文件转换df.query("foo=@bar")为 Cython。

如何复制此错误:

foo.py

import pandas as pd
bar=1
df=pd.DataFrame([1,2,3,4,5],columns=['test'])
print(df.query("test==@bar"))

安装程序.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
    Extension("sample_code",  ["foo.py"]),
]

setup(
    name = 'My Program',
    cmdclass = {'build_ext': build_ext},
    ext_modules = ext_modules
)

然后,运行python setup.py build_ext --inplace

from sample_code import foo

我得到了错误:pandas.core.computation.ops.UndefinedVariableError: local variable 'bar' is not defined

标签: pythonpandascython

解决方案


正如@hpaulj 在评论中所说:@bar不会工作,因为它使用 Python 内省机制来查找调用者的字典​​。Cython 不会生成信息。

根据文档,DataFrame.Eval您可以传递关键字参数locals_dictglobals_dict. 所以你可以这样做:

df.query("test==@bar", locals_dict={'bar': bar})

或者

df.query("test==@bar", locals_dict=locals())

值得强调的是,简单地将它放在 Cython 文件中并没有性能优势。性能将取决于 Pandas 的性能,而你编译了调用 Pandas 的文件这一事实根本没有区别。

在您的情况下,它还提供有限的“加密”优势 - 该字符串"test==@bar"肯定会在您编译的 Cython 文件中找到。


推荐阅读