将 .py 文件包含 df.query("foo=@bar") 之类的行转换为 .pyd 文件时出现 UndefinedVariableError
UndefinedVariableError when converting .py file includes lines like df.query("foo=@bar") to .pyd file
我从未使用过 Cython,但我需要加密我的源代码。
我的问题是,如何将包含 df.query("foo=@bar")
等行的 python 文件转换为 Cython。
如何重现此错误:
foo.py
import pandas as pd
bar=1
df=pd.DataFrame([1,2,3,4,5],columns=['test'])
print(df.query("test==@bar"))
setup.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
正如@hpaulj 在评论中所说:@bar
不会起作用,因为它使用 Python 内省机制来查找调用者的字典。 Cython 不生成信息。
基于the documentation for DataFrame.Eval
,您可以传递关键字参数locals_dict
或globals_dict
。所以你可以这样做:
df.query("test==@bar", locals_dict={'bar': bar})
或
df.query("test==@bar", locals_dict=locals())
值得强调的是,简单地将其放入 Cython 文件中不会带来任何性能优势。性能将由 Pandas 的性能决定,而您已经编译了调用 Pandas 的文件这一事实根本没有影响。
在您的情况下,它还提供了有限的“加密”优势 - 字符串 "test==@bar"
肯定会在您编译的 Cython 文件中找到。
我从未使用过 Cython,但我需要加密我的源代码。
我的问题是,如何将包含 df.query("foo=@bar")
等行的 python 文件转换为 Cython。
如何重现此错误:
foo.py
import pandas as pd
bar=1
df=pd.DataFrame([1,2,3,4,5],columns=['test'])
print(df.query("test==@bar"))
setup.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
正如@hpaulj 在评论中所说:@bar
不会起作用,因为它使用 Python 内省机制来查找调用者的字典。 Cython 不生成信息。
基于the documentation for DataFrame.Eval
,您可以传递关键字参数locals_dict
或globals_dict
。所以你可以这样做:
df.query("test==@bar", locals_dict={'bar': bar})
或
df.query("test==@bar", locals_dict=locals())
值得强调的是,简单地将其放入 Cython 文件中不会带来任何性能优势。性能将由 Pandas 的性能决定,而您已经编译了调用 Pandas 的文件这一事实根本没有影响。
在您的情况下,它还提供了有限的“加密”优势 - 字符串 "test==@bar"
肯定会在您编译的 Cython 文件中找到。