You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Ruby on Rails中使用PyCall调用本地Python模块失败问题排查

问题解决:Rails中调用Python脚本的路径问题与替代方案

一、当前报错原因(非语法错误)

你的代码语法没有问题,报错核心是路径配置错误:
你使用的绝对路径/lib/assets/python指向的是系统根目录下的lib文件夹,而非你的Rails项目根目录内的对应路径。PyCall无法定位到目标Python文件,因此抛出ModuleNotFoundError。

二、修正PyCall的代码

利用Rails提供的Rails.root获取项目根目录,拼接出正确的Python文件所在路径:

require 'pycall'
# 拼接项目内的完整路径
python_dir = Rails.root.join('lib', 'assets', 'python').to_s
PyCall.sys.path.append(python_dir)
file_import = PyCall.import_module("the_file")

三、Rails中运行Python脚本的其他方案

1. 直接执行系统命令

如果不需要在Ruby和Python间传递复杂数据,可直接用Ruby的系统命令执行脚本:

# 基础写法
system("python3 #{Rails.root.join('lib', 'assets', 'python', 'the_file.py')}")

# 安全写法(避免shell注入,同时捕获输出和错误)
require 'open3'
stdout, stderr, status = Open3.capture3("python3", Rails.root.join('lib', 'assets', 'python', 'the_file.py').to_s)
# stdout为脚本输出内容,stderr为错误信息,status.exitstatus为脚本退出码

2. 封装为Rake任务

若需定时或批量执行Python脚本,可封装成Rake任务便于调用:

# lib/tasks/python_task.rake
namespace :python do
  desc "执行目标Python脚本"
  task run_script: :environment do
    python_path = Rails.root.join('lib', 'assets', 'python', 'the_file.py').to_s
    system("python3 #{python_path}")
    puts "Python脚本执行完成"
  end
end

终端调用方式:bundle exec rake python:run_script

3. 后台异步执行

如果Python脚本执行耗时较长,建议用Sidekiq等框架异步处理,避免阻塞Web请求:

# app/workers/python_script_worker.rb
class PythonScriptWorker
  include Sidekiq::Worker

  def perform
    python_path = Rails.root.join('lib', 'assets', 'python', 'the_file.py').to_s
    system("python3 #{python_path}")
  end
end

调用方式:PythonScriptWorker.perform_async


内容的提问来源于stack exchange,提问作者Benjamin Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 21:13:14